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));
}