Как выводить только существующие параметры?

Есть Кот с 1 полем. (конструктор) Есть Кот с 2 полями. (конструктор) Есть Кот с 3 полями. (конструктор)

Кот должен уметь выводить полную информацию о себе в консоль, при этом если какой-то параметр неизвестен , то информация об этом параметре не выводится. Как реализовать такой метод ?


Ответы (2 шт):

Автор решения: Eugene X

Мульти конструктор в java реализовывается просто перегрузкой метода с разными параметрами.

class HelloWorld {
    
    private String name = null;
    private String surname = null;
    private int age = 0;
    
    public HelloWorld(String name) {
        this.name = name;
    }
    
    public HelloWorld(String name, String surname) {
        this.name = name;
        this.surname = surname;
    }
    
    public HelloWorld(String name, String surname, int age) {
        this.name = name;
        this.surname = surname;
        this.age = age;
    }
    
    public String toString() {
        String result = name;
        if (surname != null) {
            result += " " + surname;
        }
        if (age != 0) {
            result += " am " + String.valueOf(age) + " years old";
        }
        return result;
    }
    
    public static void main(String[] args) {
        var hw = new HelloWorld("Eugene");
        System.out.println(hw);
    }
}
→ Ссылка
Автор решения: ulxanxv

Самый лучший вариант написать класс типа ToStringHelper (возможно, моя реализация не самая лучшая, но для идеи сойдет, думаю) ::

private static class ToStringHelper {
    private final Map<String, Object> fields;
    private final String className;

    public ToStringHelper(Object target) {
        this.fields = new HashMap<>();
        this.className = target.getClass()
                .getSimpleName();
    }

    public ToStringHelper add(String key, Object value) {
        if (key != null && value != null) {
            fields.put(key, value);
        }

        return this;
    }

    @Override
    public String toString() {
        final StringBuilder formattedFields = new StringBuilder(32)
                .append(className)
                .append("{");

        String separator = "";
        for (Map.Entry<String, Object> entry : fields.entrySet()) {
            formattedFields.append(separator);
            separator = ", ";

            Object value = entry.getValue();
            if (value.getClass().isArray()) {
                Object[] array = {value};
                value = Arrays.deepToString(array);
            }

            formattedFields.append(entry.getKey())
                    .append("=")
                    .append(value);
        }

        return formattedFields.append("}").toString();
    }
}

А затем в своих классах использовать очень простую конструкцию ::

private static class Cat {
    private final String name;

    private Integer age;
    private Integer weight;

    public Cat(String name) {
        this.name = name;
    }

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Cat(String name, int age, int weight) {
        this.name = name;
        this.age = age;
        this.weight = weight;
    }

    @Override
    public String toString() {
        return new ToStringHelper(this)
                .add("name", name)
                .add("age", age)
                .add("weight", weight)
                .toString();
    }
}

Тест ::

    final Cat ivanCat = new Cat("Ivan");
    final Cat sergeyCat = new Cat("Sergey", 12);
    final Cat dmitriyCat = new Cat("Dmitriy", 15, 16);

    System.out.println(ivanCat); // Cat{name=Ivan}
    System.out.println(sergeyCat); // Cat{name=Sergey, age=12}
    System.out.println(dmitriyCat); // Cat{name=Dmitriy, weight=16, age=15}

P.S. Не забывайте о том, что простые типы данных (int, double, float и др.) не могут иметь значение null, поэтому и провалидировать вы их особо и не сможете. Например, если не задать значение для поля int в классе, то его значение будет 0, а если использовать обёртки типа Integer, то будет null

→ Ссылка