3

I've looked at several answers already, and I am getting errors with the answers that I've found. I'm trying to convert an ArrayList of Doubles[] to a normal double 2D array. My code:

    public ArrayList<Double[]>  ec;
    public double[][]           ei;
    ...
    encogCorpus = new ArrayList<Double[]>();
    ...
    ec.add(inputs);
    ...
    ei = new double[ec.size()][];

    for (int i = 0; i < ec.size(); i++) {
        ArrayList<Double> row = ec.get(i);
        ei[i] = row.toArray(new double[row.size()]);
    }

I'm getting errors that say

Type mismatch: cannot convert from Double[] to ArrayList

And

The method toArray(T[]) in the type ArrayList is not applicable for the arguments (double[])

4 Answers 4

4

Problems

  1. First of all, ec here is of type ArrayList<Double[]>, which means ec.get(i) should return Double[] and not ArrayList<Double>.
  2. Second, double and Double are completely different types. You can't simply use row.toArray(new double[row.size()]) on your code.

Solutions

1.

If you want a true 2D ArrayList of Doubles then the type of ec should be ArrayList<ArrayList<Double>>. But because we can't use toArray(), we manually loop instead.

public ArrayList<ArrayList<Double>> ec;  // line changed here
public double[][]                   ei;
...
encogCorpus = new ArrayList<ArrayList<Double>>(); // and here also
...
ec.add(inputs); // `inputs` here should be of type `ArrayList<Double>`
...
ei = new double[ec.size()][];

for (int i = 0; i < ec.size(); i++) {
    ArrayList<Double> row = ec.get(i);

    // Perform equivalent `toArray` operation
    double[] copy = new double[row.size()];
    for (int j = 0; j < row.size(); j++) {
        // Manually loop and set individually
        copy[j] = row.get(j);
    }

    ei[i] = copy;
}

2.

But if you insist of using ArrayList<Double[]>, we only need to change the main part:

public ArrayList<Double[]>  ec;
public double[][]           ei;
...
encogCorpus = new ArrayList<Double[]>();
...
ec.add(inputs);
...
ei = new double[ec.size()][];

for (int i = 0; i < ec.size(); i++) {
    // Changes are only below here

    Double[] row = ec.get(i);
    double[] copy = new double[row.length];

    // Still, manually loop...
    for (int j = 0; j < row.length; j++) {
        copy[j] = row[j];
    }

    ei[i] = copy;
}

3.

Finally, if you could change Double[] to double[], solution 2 would become,

public ArrayList<double[]>  ec; // Changed type
public double[][]           ei;
...
...
for (int i = 0; i < ec.size(); i++) {
    // Simpler changes here
    ei[i] = ec.get(i).clone();
}
...
Sign up to request clarification or add additional context in comments.

8 Comments

I changed ec to public ArrayList<double[]> and the ec.add(inputs) seems to work, but the '// Changes are only below here' doesn't work then.
@jonbon, my mistakes, there was a weird typo!
@jonbon, I have edited my answer! But still, I can't believe I didn't saw that, and no one also saw that.
I am able to change to double[] instead of Double[]. Will I only need to use 1 for loop and use clone() then?
@jonbon I recommend clone. Its faster, both by typing and by runtime :)
|
3

Basically all you need to do is this:

for (int i = 0; i < ec.size(); i++) {
    Double[] boxedRow = ec.get(i);
    double[] unboxedRow = new double[boxedRow.length];
    for (int j = 0; j < boxedRow.length; j++)
        unboxedRow[j] = boxedRow[j];
    ei[i] = unboxedRow;
}

You're having trouble because of boxing / unboxing. Manually unboxing the Doubles to doubles allows us to convert the array to the right type.

An alternate solution would be this:

public ArrayList<Double[]>  ec;
public Double[][]           ei; // no need to unbox

// ...

for (int i = 0; i < ec.size(); i++) {
    ei[i] = ec.get(i);
}

I'll add that your current solution is not a 2D ArrayList; it is an ArrayList of Double arrays. It looks like what you might be trying to do is something like this:

public ArrayList<ArrayList<Double>>  ec;
public double[][]                    ei;

// ...

for (int i = 0; i < ec.size(); i++) {
    ArrayList<Double> row = ec.get(i);
    Double[] rowArray = row.toArray(new Double[row.size()]);
    double[] unboxedRow = new double[rowArray.length];
    for (int j = 0; j < rowArray.length; j++)
        unboxedRow[j] = rowArray[j];
    ei[i] = unboxedRow;
}

Which, again, could potentially be this:

public ArrayList<ArrayList<Double>>  ec;
public Double[][]                    ei;

// ...

for (int i = 0; i < ec.size(); i++) {
    ArrayList<Double> row = ec.get(i);
    ei[i] = row.toArray(new Double[row.size()]);
}

Finally, please note that when you instantiate a new Double[], the arrays initialize to null and not to 0. If you try the following, you'll get a NullPointerException, though it will compile.

Double[] boxedArray = new Double[1];
double unboxed = boxedArray[0]; // equiv to "double unboxed = null;"

You need to be careful when unboxing, and make sure that you are handling nulls correctly.

3 Comments

Awesome answer, thanks so much. When I change to ArrayList<ArrayList<Double>> I can no longer ec.add(item) when item is a double[]?
It's tricky, because a Double[] is really an array of pointers that point to Doubles (or null). A double[] is an array of doubles, so the actual values are stored in the array, instead of just pointers. This is why a double[] never contains null. This makes it that we have to manually "box" our doubles into an array of pointers (Double references) in an array we specify. Java cannot just implicitly convert a double[] to a Double[].
Another solution, if possible, is to simply use double[] instead of Double[]. So that a simple clone() can be done.
3
List<double[]> list = Arrays.asList(new double[]{1.1, 2.0}, new double[]{3.0, 5.8});
double[][] res = list.toArray(new double[list.size()][]);
// System.out.println(Arrays.deepToString(res));

Same approach to convert ArrayList to 2d int array.

Comments

0

Error is in the following lines:

for (int i = 0; i < ec.size(); i++) {
    ArrayList<Double> row = ec.get(i);
    ei[i] = row.toArray(new double[row.size()]);
}

The first error will be resolved by replacing ArrayList<Double> with Double[]:

for (int i = 0; i < ec.size(); i++) {
    Double[] row = ec.get(i);
    ei[i] = row.toArray(new double[row.size()]);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.