Question

I'm reading "Effective Java" by Joshua Bloch now and when I read item 41 "Use overloading judiciously" I was confused because of the example used there. I tried it on computer and it indeed does what it does in the book. But I don't understand why!

Here's this example:

public class SetList {
    public static void main(String[] args) {
        Set<Integer> set = new TreeSet<Integer>();
        List<Integer> list = new ArrayList<Integer>();
        for (int i = -3; i < 3; i++) {
            set.add(i);
            list.add(i);
        }
        for (int i = 0; i < 3; i++) {
            set.remove(i);
            list.remove(i);
        }
        System.out.println(set + " " + list);
    }
}

It outputs:

[-3, -2, -1] [-2, 0, 2]

I understand that list.remove() in this example should remove by index but it doesn't! After list was filled with values it was: [-3, -2, -1, 0, 1, 2]. So, when we remove 0, 1 and 2 elements we should stay with [0, 1, 2] and not with [-2, 0, 2]. What's going on there?

Was it helpful?

Solution

The list items are removed one-by-one and when items are removed from the list, the indexes of everything that comes after it are shifted back. This is why the indexes end up referring to different items than in the initial position.

If you can't see this easily, step through the code in a debugger or even "run" the list manipulations manually on paper, step by step.

OTHER TIPS

This is just elaborating on Matti's answer really. I couldn't get this clearly in a comment.

Look at the list after elements are added:

[-3 -2 -1 0 1 2]

Remove element 0

[-2 -1 0 1 2]

Remove element 1 - which is now the same as the old element 2

[-2 0 1 2]

Remove element 2 - which is now the same as the old element 4

[-2 0 2]

There we go.

To make it even clearer, try reversing the order of the for and remove elements 2, then 1, then 0. You will get the answer you originally expected.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top