Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error occured while using java foreach statements

Tags:

java

My code as follows

public class Test {

    public static void main(String[] args) {
        int count1 = 0, count2 = 0;
        Test[] test1 = new Test[5];
        Test[] test2 = new Test[5];
        if (test1 == null || test2 == null)
            System.out.println("null");
        for (int j = 0; j < 3; j++) {
            for (int i = 0; i < test1.length; i++) {
                if (test1[i] == null) {
                    test1[i] = new Test();
                    count1++;
                }
            }
        }
        for (int j = 0; j < 3; j++) {
            for (Test test : test2) {
                if (test == null) {
                    test = new Test();
                    count2++;
                }
            }
        }
        System.out.println(count1 + " " + count2);
    }
}

I run the program and I found its output is 5 15. It made me confused,I can't understand what differences between using for statements and using foreach statements.Thanks for giving me a hand.

like image 658
dapao Avatar asked May 10 '16 10:05

dapao


2 Answers

Changes to the iteration variable in an enhanced-for statement do not affect the underlying collection. So while this modifies the array:

test[i] = new Test(); // In for loop

... this doesn't:

test = new Test(); // In enhanced for loop

Because the array isn't modified, the next time you iterate over it, the values are still null, so you'll increment your counter another 5 times. Ditto the third time you iterate over the array.

The moral of the story is: don't use an enhanced for loop if you want to modify the content of the collection/array.

Note that changes to the objects whose references are already stored in the collection/array doesn't count as modifying the collection/array. So if you'd already populated the collection and had some setName() method, then this:

for (int i = 0; i < test1.length; i++) {
    test[i].setName("foo");
}

would be equivalent to:

for (Test test : test1) {
    test.setName("foo");
}

That's not changing the array, which just contains references to objects - instead, it's changing the data within those objects.

like image 93
Jon Skeet Avatar answered Oct 11 '22 13:10

Jon Skeet


You can't modify the underlying data structure using the extended for-loop ("foreach"), your test = new Test(); doesn't change the array.

like image 45
Landei Avatar answered Oct 11 '22 13:10

Landei