Java: множественные конструкторы, заставляющие повторное использование кода?

У меня есть класс, где один из его членов ArrayList<ArrayList<Double>> elementsи поэтому у меня есть конструктор, который принимает тот же тип, и все хорошо.

public elementArray(ArrayList<ArrayList<Double>> elements)
{
    this.elements =  elements;
    // a bunch of other stuff happens
}

Тем не менее, я также должен быть в состоянии построить с вводом типа Double[][], поэтому я сначала конвертирую его в тип списка 2D, а затем вызываю оригинальный конструктор...

public elementArray(Double[][] array)
{
    // convert Double[][] array to ArrayList<ArrayList<Double>> elements
    this(elements);
}

Только я не могу вызвать другой конструктор, кроме как первым, что происходит в моем конструкторе! Я обречен копировать-вставить здесь, или есть умный способ сделать то, что я хочу?

4 ответа

Решение

Одним из решений было бы извлечь преобразование в статический метод:

public elementArray(Double[][] array) {
    this(convert(elements));
}

private static ArrayList<ArrayList<Double>> convert(Double[][] array) {
    // convert Double[][] array to ArrayList<ArrayList<Double>> elements
}

Вы не можете иметь код до звонка this()Вы также не можете вызывать другие методы экземпляра.

Вы можете извлечь это преобразование в отдельный статический метод:

private static ArrayList<ArrayList<Double>> arrayToList(Double[][] d) {
    //convert and return list
}

И снова используйте этот метод в вашем втором конструкторе:

public elementArray(Double[][] array) {
    this(arrayToList(array));
}

Обычный шаблон для использования будет использовать вместо этого Builder.

https://iluwatar.github.io/java-design-patterns/patterns/builder/

Или статический фабричный метод.

https://iluwatar.github.io/java-design-patterns/patterns/factory-method/

Например, используя статический метод фабрики, у вас будет только один (возможно, частный) конструктор, который принимает самую чистую версию того, что нужно вашему классу.

public class elementArray{
    public elementArray(ArrayList<ArrayList<Double>> elements)
    {
        this.elements =  elements;
        // a bunch of other stuff happens
    }
    public static elementArray create(Double[][] array)
    {
        // convert Double[][] array to ArrayList<ArrayList<Double>> elements
        return new elementArray(elements);
    }
    public static elementArray create(ArrayList<ArrayList<Double>> elements)
    {
        return new elementArray(elements);
    }
}

и затем вместо вызова конструктора вы вызываете статические методы.

elementArray.create(new double[][]{{1.0d},{2.0d}});

Это довольно часто использовалось в недавней Java, в Guava и стандартной библиотеке Java.

увидеть Arrays.asList https://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html

Но лучше использовать список вместо ArrayList.

    public elementArray(Double[][] array) {
        this(convert(elements));
    }

    static ArrayList<ArrayList<Double>> convert(Double[][] elements) {
        return IntStream.range(0, elements.length)
                .mapToObj(i -> IntStream.range(0, elements[i].length)
                        .mapToObj(j -> elements[i][j])
                        .collect(ArrayList::new, List::add, (u, v) -> u.addAll(v)))
                .collect(ArrayList::new,
                        (u, v) -> v.add(u),
                        (u, v) -> u.addAll(v));
    }
Другие вопросы по тегам