How does the enhanced for statement work for arrays, and how to get an iterator for an array?

166,983

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();
Share:
166,983

Related videos on Youtube

Emil
Author by

Emil

☸Java Programmer☸

Updated on July 05, 2022

Comments

  • Emil
    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:

    1. How does the above for-each loop work?
    2. How do I get an iterator for an array in Java?
    3. Is the array converted to a list to get the iterator?
    • Ciro Santilli OurBigBook.com
      Ciro Santilli OurBigBook.com about 9 years
      A what is faster version: stackoverflow.com/questions/1006395/…
    • lue
      lue about 4 years
      Above question about performance has been closed. It is answered here: stackoverflow.com/questions/256859/…
    • Elisabeth
      Elisabeth almost 4 years
      I 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
    st0le over 13 years
    Yes, +1 It's prolly just a regular for. @Emil, you can't.
  • Emil
    Emil over 13 years
    I don't think it will work.Arrays.asList(arr) will return List of type int[].Since it is primitive array.
  • Konrad Rudolph
    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 a List<Integer>.
  • Sean Patrick Floyd
    Sean Patrick Floyd over 13 years
    @emil it works because Arrays.asList takes a varargs parameter
  • Emil
    Emil over 13 years
    @seanizer:but i tried the above code in my IDE and it shows error.
  • Sean Patrick Floyd
    Sean Patrick Floyd over 13 years
    it compiles in my eclipse. have you set the compiler compliance to at least 1.5 ?
  • ILMTitan
    ILMTitan over 13 years
    Arrays.asList() can not take an int[], only Object[] and subclasses.
  • chakrit
    chakrit about 10 years
    This 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 specify Iterator<int> or Iterator<Integer>
  • njzk2
    njzk2 almost 10 years
    this is wrong. this returns a List<int[]>, and hence an Iterator<int[]>, not a List<Integer>!
  • Khaled.K
    Khaled.K over 9 years
    You're converting the array into a list just to provide an iterator ?!
  • Khaled.K
    Khaled.K over 9 years
    Agree. Or build your own ArrayIterator, if you want to keep using the primitive data-type
  • Mark Jeronimus
    Mark Jeronimus about 9 years
    Code completion doesn't show any suggestions for ArrayIt; assuming all 3rd party libraries.
  • keyboardr
    keyboardr almost 9 years
    Effective 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
    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
    Michael Schmeißer almost 8 years
    The most complete answer in my opinion, but I think you should replace mapToObj(Integer::new) with mapToObj(Integer::valueOf)
  • Zenexer
    Zenexer almost 8 years
    It seems you're right, @MichaelSchmeißer. Thanks for the tip. I've updated the answer accordingly.
  • lue
    lue about 4 years
    @Khaled.K, see Zenexer's (stackoverflow.com/users/1188377/zenexer) new answer.
  • Elisabeth
    Elisabeth almost 4 years
    Are 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." ???