Explain Codes LogoExplain Codes Logo

Why is an array not assignable to Iterable?

java
iterable
arrays
collections
Anton ShumikhinbyAnton Shumikhin·Jan 12, 2025
TLDR

Arrays in Java don't implement the Iterable interface since they're older than the collections and generics framework. However, an array can work with the enhanced for loop and other Iterable contexts if it's enveloped with Arrays.asList(). Here’s how you can accomplish that:

Integer[] array = {1, 2, 3}; Iterable<Integer> iterable = Arrays.asList(array); // Now `iterable` can be used wherever Iterable is needed. No array is an island.

This approach lets you handle the original array as an Iterable without additional overhead.

Deep-dive into arrays and Iterable

Despite their simplicity and efficiency, arrays come with limitations—they don't support the methods required by the Iterable interface, such as iterator(). Arrays were conceived before collections and generics. They're considered more primitive and don't naturally conform to newer interfaces that came with the evolution of the language.

If we want our arrays to step into the Iterable limelight, we've got to hit this conversion problem with a good old fashioned workaround: wrapping it with a List using Arrays.asList().

Trade-offs with arrays

Arrays possess certain unique traits. They are cloneable and serializable, making them handy for quick duplication or persistence. However, char[] does not override its toString() method, which could affect performance when string conversion is needed:

char[] hello = {'H', 'e', 'l', 'l', 'o'}; System.out.println(hello); // Well, hello to you too.

Converting arrays to Iterable

We can transform an array into an Iterable using Arrays.asList(yourArray). This technique creates an fixed-size list backed by the original array, like a punctual but rigid personal assistant. The resulting list is not resizable, but it does provide the missing iterator() method.

int[] primitives = {1, 2, 3}; Iterable<Integer> iterableBoxed = IntStream.of(primitives).boxed().collect(Collectors.toList()); // Primitive no more // Now the `iterableBoxed` can be used wherever Iterable is needed.

Note For handling primitive arrays (e.g., int, double, char) as Iterable, we must use streams to ensure the proper Iterable instance is created.

To be (an array) or not to be (an array)

The choice between an array and a Collection depends heavily on the specific requirements:

Please use arrays when:

  • Efficiency is priority
  • Index-based access is frequent
  • Size is fixed and known upfront

Opt for Collection when:

  • You need dynamic resizing
  • Enhanced iteration is required
  • Type-safety and readability are vital (Generic types are your friend here)

Brief history lesson on Java arrays

The fact that arrays don't implement Iterable isn't just an oversight by Java creators—it's primarily a result of how the language has evolved. Making arrays Iterable could introduce significant complexity due to backward compatibility issues and lead to profound changes in the language design.

Many design decisions in Java originate from its early design choices. For instance, when the for-each loop was introduced in Java 5, it was also enabled for arrays. Dig into the compiled bytecode and you'll discover that this loop gets implemented as a plain old for loop, doing its job without the glitz and glamour.

And just as a side note, things play out differently in other languages. For example, in .NET 4.5 you can iterate over arrays, but that's a different story with different people in different universes.