How does the enhanced for statement work for arrays, and how to get an iterator for an array?
Solution 1
If you want an Iterator
over an array, you could use one of the direct implementations out there instead of wrapping the array in a List
. For example:
Apache Commons Collections ArrayIterator
Or, this one, if you'd like to use generics:
com.Ostermiller.util.ArrayIterator
Note that if you want to have an Iterator
over primitive types, you can't, because a primitive type can't be a generic parameter. E.g., if you want an Iterator<int>
, you have to use an Iterator<Integer>
instead, which will result in a lot of autoboxing and -unboxing if that's backed by an int[]
.
Solution 2
No, there is no conversion. The JVM just iterates over the array using an index in the background.
Quote from Effective Java 2nd Ed., Item 46:
Note that there is no performance penalty for using the for-each loop, even for arrays. In fact, it may offer a slight performance advantage over an ordinary for loop in some circumstances, as it computes the limit of the array index only once.
So you can't get an Iterator
for an array (unless of course by converting it to a List
first).
Solution 3
Arrays.asList(arr).iterator();
Or write your own, implementing ListIterator interface..
Solution 4
Google Guava Libraries collection provides such function:
Iterator<String> it = Iterators.forArray(array);
One should prefere Guava over the Apache Collection (which seems to be abandoned).
Solution 5
In Java 8:
Arrays.stream(arr).iterator();
Related videos on Youtube
Comments
-
Emil almost 2 years
Given the following code snippet:
int[] arr = {1, 2, 3}; for (int i : arr) System.out.println(i);
I have the following questions:
- How does the above for-each loop work?
- How do I get an iterator for an array in Java?
- Is the array converted to a list to get the iterator?
-
Ciro Santilli OurBigBook.com about 9 yearsA what is faster version: stackoverflow.com/questions/1006395/…
-
lue about 4 yearsAbove question about performance has been closed. It is answered here: stackoverflow.com/questions/256859/…
-
Elisabeth almost 4 yearsI am not finding an answer to point 1 that is definitive. Does the for each loop test the type of the item being iterated over, and use a regular for loop under the covers if it's an array? Or does it create an Iterable on the fly? Or does it convert to a List? I haven't found a definitive answer to this.
-
st0le over 13 yearsYes, +1 It's prolly just a regular
for
. @Emil, you can't. -
Emil over 13 yearsI don't think it will work.Arrays.asList(arr) will return List of type int[].Since it is primitive array.
-
Konrad Rudolph over 13 years@Emil: Java generics don’t work for primitive types.
Arrays.asList
implicitly takes care of this by boxing the values in the array. Hence, the result really is aList<Integer>
. -
Sean Patrick Floyd over 13 years@emil it works because Arrays.asList takes a varargs parameter
-
Emil over 13 years@seanizer:but i tried the above code in my IDE and it shows error.
-
Sean Patrick Floyd over 13 yearsit compiles in my eclipse. have you set the compiler compliance to at least 1.5 ?
-
ILMTitan over 13 years
Arrays.asList()
can not take anint[]
, onlyObject[]
and subclasses. -
chakrit about 10 yearsThis is usually the best answer except when we're dealing with array of primitives (such as
int[]
) then this no longer works :( since we can't specifyIterator<int>
orIterator<Integer>
-
njzk2 almost 10 yearsthis is wrong. this returns a
List<int[]>
, and hence anIterator<int[]>
, not aList<Integer>
! -
Khaled.K over 9 yearsYou're converting the array into a list just to provide an iterator ?!
-
Khaled.K over 9 yearsAgree. Or build your own ArrayIterator, if you want to keep using the primitive data-type
-
Mark Jeronimus about 9 yearsCode completion doesn't show any suggestions for
ArrayIt
; assuming all 3rd party libraries. -
keyboardr almost 9 yearsEffective Java is wrong if it's an empty Collection. In that case, it will create an Iterator unnecessarily. This leads to Object churn. The fix is to wrap it in an isEmpty() check. This is particularly important on memory constrained devices like Android.
-
Jasper about 8 years@KhaledKhnifer There's really not much converting going on.
Arrays.asList()
uses the actual array and wraps it in a class that adapts it to the list interface. So except for the "not supporting primitives" issue (and for people who came here with the same issue in a non-primitive situation) this is actually a good solution. -
Michael Schmeißer almost 8 yearsThe most complete answer in my opinion, but I think you should replace
mapToObj(Integer::new)
withmapToObj(Integer::valueOf)
-
Zenexer almost 8 yearsIt seems you're right, @MichaelSchmeißer. Thanks for the tip. I've updated the answer accordingly.
-
lue about 4 years@Khaled.K, see Zenexer's (stackoverflow.com/users/1188377/zenexer) new answer.
-
Elisabeth almost 4 yearsAre we sure it's not creating an Iterable for the array, or converting the array to a List? In other words, inside, Java is saying "if the type is an array then use a regular for loop with a hidden index, otherwise, use the Iterable." ???