我有一个类,其中一个成员是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);
}
只是,我不能调用另一个构造函数,除非在我的构造函数中发生的第一件事!我注定要在这里复制粘贴,还是有聪明的方法可以做我想做的事?
一种解决方案是将转换提取为静态方法:
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));
}
一种常见的模式是改用生成器。
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#asList-T...-
但最好使用 List 而不是 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));
}