In a linked list, it takes a long time to go from element 0 to element 1000000. So the Iterator keeps a reference to element n so it only has to go one step to get to element n + 1. You should therefore not use myList.get(i) on a linked list:-… will run in quadratic time on a linked list. On an array list however (which includes Vector) there is no need to go from element 0 to element 1000000. Calling an index of an array runs in constant time and it can take as little as 1 clock cycle to find element 1000000. The above code will run at least as fast on an array list as using an Iterator. Now look at the RandomAccess interface again.
As for what the difference between using the enhanced for loop and using the iterator directly, you would use the iterator directly if you need to modify the list as you're traversing it. Here's an example:
No. The reason that ConcurrentModificationException is thrown is because removing an object leaves an iteration in an undefined state. Imagine the following iteration:
1 2 3 4 5 6
We remove the element. Now, what should the current iteration state be?
1 3 4 5 6
1 3 4 5 6
You may be tempted to say the first option, but the pointer hasn't advanced yet. That means that for the next step, the element 3 is skipped. You can see this is already confusing stuff for simple array lists, and it becomes even more complex when the data type may go through a huge structural change on removal of an element, for example, hash maps and trees. That's why you can't structurally change a collection while you're iterating it.
The iterator class however, *always* has a set definition for what the next element is. After you remove an element using the iterator, calling next() will return the correct element in the iteration order. It will only throw an exception if you structurally change the collection using anything else but that iterator, including another iterator.
The code as you posted it will run just fine. However, if you uncomment the print statement, then you will indeed get the exception you reported. Remember: every time you call next() on an iterator, you advance to the next element. You check if you have more elements to iterate over in the loop condition with hasNext(), and then you proceed in to the loop body. What happens if you only have one element left to iterate over before entering the loop?
You see it uses the same logic as yours; deleting .intValue() in line 27 made no difference. I suffered no Exceptions. That isn't quite true; if I passed -99999999999999999 as an argument I got a NumberFormatException
JB is correct; if you use next() twice in the loop you are liable to run out of List if you have an odd number of elements.
I think you can create a new List minus the 3 like this in Java8 only:-
List<Integer> listWithout3 = list.stream().filter(i != 3).collect(Collectors.toList());
In the constructor you have a String which you turn into a Stream<String> with the method of the Arrays class.
Then you use the map method to create a different kind of Stream; the bit with :: in the middle means call the valueOf(String) method of the Integer class. The compiler will presume you want to pass a String to that method because you are inside a Stream of Strings. Now you have a Stream<Integer>.
Then you use the collect method which uses a Collector object to create a List. The actual Collector object is that whose reference is returned from the toList method.
Instead of using the Iterator, the second line uses the stream method, actually in the Collection interface, to create a Stream; since the List is a List<Integer> the Stream will be a Stream<Integer>. The filter() method can test whether the value is 3 or not. You want to keep everything which is not equal to 3. The compiler “knows” that it is possible to use the intValue method or unboxing, so you can use != 3. Then you turn it back to a List with exactly the same technique with toList.
Just let me do the talking. Ahem ... so ... you see ... we have this tiny ad...