Reputation: 236
I have a class where one of its members is ArrayList<ArrayList<Double>> elements
, and so I have a constructor that takes in that same type and all is good.
public elementArray(ArrayList<ArrayList<Double>> elements)
{
this.elements = elements;
// a bunch of other stuff happens
}
However, I also need to be able to construct with an input of type Double[][]
, so I first convert it to the 2D list type, and then call the original constructor...
public elementArray(Double[][] array)
{
// convert Double[][] array to ArrayList<ArrayList<Double>> elements
this(elements);
}
Only, I can't call another constructor except as the first thing that happens in my constructor! Am I doomed to copy-paste here, or is there a clever way to do what I want?
Upvotes: 1
Views: 244
Reputation: 728
But it is better to use the List instead of 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));
}
Upvotes: -1
Reputation: 4470
A common pattern to use would be to use a Builder instead.
https://iluwatar.github.io/java-design-patterns/patterns/builder/
Or a static factory method.
https://iluwatar.github.io/java-design-patterns/patterns/factory-method/
e.g. Using a static factory method, you would have only a single (possibly private) constructor, that accepts the rawest version of what your class needs.
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);
}
}
and then, instead of invoking the constructor, you would call the static methods.
elementArray.create(new double[][]{{1.0d},{2.0d}});
This has been used fairly commonly in recent Java, in Guava and the Java standard library.
see Arrays.asList
https://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html#asList-T...-
Upvotes: 3
Reputation: 45309
You can't have code before the call to this()
, you also can't call other instance methods.
You can extract that conversion into a separate static method:
private static ArrayList<ArrayList<Double>> arrayToList(Double[][] d) {
//convert and return list
}
And reuse this method in your second constructor:
public elementArray(Double[][] array) {
this(arrayToList(array));
}
Upvotes: 3
Reputation: 2890
One solution would be to extract the conversion into a static method:
public elementArray(Double[][] array) {
this(convert(elements));
}
private static ArrayList<ArrayList<Double>> convert(Double[][] array) {
// convert Double[][] array to ArrayList<ArrayList<Double>> elements
}
Upvotes: 3