简体   繁体   中英

Why can't I assign 1D arrays to 2D array using foreach cycle?

I have a method that returns 1D array. I want to call the method in a cycle and store the results in an 2D array. When using foreach cycle it doesn't work, the array results is full of null pointers.

//this doesn't work
...
double[][] results = new double[20][];
for(double[] result : results){
        result = method();
}
...
public double[] method(){
        double[] ret = new double[15];
        //populate ret and do other stuff...
        return ret;
}

But when using regular "for" cycle for iterating over the array it magically works!

...
double[][] results =  new double[20][];
for(int i=0;i<20;i++){
        results[i]=method();
}
...   
public double[] method(){
        double[] ret = new double[15];
        //populate ret and do other stuff...
        return ret;
}

Why?

Because in the enhanced for loop you access to a copy of each object reference of the arrays which is assigned to a variable, and you're modifying the value of this variable, not its contents.

for (double[] result :  results) {
     //here result is just a copy of results[0], results[1] and on...
     //if you modify value of result i.e. assigning a new value
     //you're just changing the value of the current variable
     //note that if you modify an object inside the variable is reflected
     //since you're updating the state of the reference, which is valid
}

This code can be somewhat translated to:

for (int i = 0; i < results.length; i++) {
     double[] result = results[i];
     //this explains why the enhanced for doesn't work
     result = method();
}

Because, in your loop, result is a copy of the reference stored in the array. And you assign a new array to this copy. So the initial reference is left unmodified:

Before the assignment

results[i] ----> null
                  ^
result -----------|

After the assignment:

results[i] ----> null

result --------> double array

It doesn't work in the first example because you are not using an index when you assign the 1D array to your 2D array :

result = method();

Here result is only a local variable, whose scope is the foreach loop, so you are only assigning the array to this local variable. The 2D array remains unchanged.

You could manage it using foreach with a manual index, setting to 0 before entering the loop and manually incrementing it. But in this case the classic for loop is probably better suited.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM