Explain Codes LogoExplain Codes Logo

Convert Java Array to Iterable

java
java-8
streams
functional-programming
Alex KataevbyAlex Kataev·Feb 3, 2025
TLDR

To convert a array to an Iterable, you may use Arrays.asList():

Integer[] nums = {1, 2, 3}; Iterable<Integer> iterable = Arrays.asList(nums);

And here is iteration in action:

for (Integer num : iterable) { System.out.println(num); }

Keep in mind that any changes to iterable reflect in nums. For a modifiable Iterable, do:

Iterable<Integer> modifiable = new ArrayList<>(Arrays.asList(nums));

But when we talk about primitive arrays, such as int[], Arrays.asList() won't come to our rescue. We need to scout out different methods, as detailed below.

Handling primitive arrays: Step up, Java 8 streams!

To convert int[] to Iterable<Integer>, Java 8 Streams swoops in to save the day:

int[] primitiveNums = {1, 2, 3}; Iterable<Integer> iterableBoxed = IntStream.of(primitiveNums) .boxed() .collect(Collectors.toList()); // Streams: Fast & Flow-rious!

In the above, IntStream.of(primitiveNums).boxed() autoboxes our int to Integer, making it compatible with Iterable<Integer>.

Dodging the Array.asList() bullet

Ye Olde Rule: Do not use Arrays.asList() directly on primitives. Here's why:

int[] primitiveArray = {1, 2, 3}; Iterable<int[]> incorrectIterable = Arrays.asList(primitiveArray); // Wait! There's only one element in this Iterable, and that's the whole array!

External libraries to the rescue

Fret not, Guava's Ints.asList() is here to aid:

int[] primitives = {1, 2, 3}; Iterable<Integer> guavaIterable = Ints.asList(primitives); // Guava: Making lives less primitive!

Guava handles the autoboxing internally. Thus, providing a clean, efficient solution without racking your brains on streams or crafting custom implementations.

Go Custom, when there's no other way

At times, you might want to roll up your coding sleeves and create a custom Iterable for your array:

public class ArrayIterable<T> implements Iterable<T> { private final T[] array; public ArrayIterable(T[] array) { this.array = array; } @Override public Iterator<T> iterator() { return new Iterator<>() { private int index = 0; @Override public boolean hasNext() { return index < array.length; } @Override public T next() { if (!hasNext()) throw new NoSuchElementException(); return array[index++]; } }; } } // Warning: Contains craftmanship!

Apply it like:

int[] primitiveNums = {1, 2, 3}; ArrayIterable<Integer> customIterable = new ArrayIterable<>(IntStream.of(primitiveNums) .boxed() .toArray(Integer[]::new));

When arrays meet functional programming

The Iterable functional interface

Java 8's functional interfaces meet lambda expressions to make everything more concise:

int[] primitiveNums = {1, 2, 3}; Iterable<Integer> lambdaIterable = () -> IntStream.of(primitiveNums) .boxed() .iterator(); // Lambda: The (code)blockbuster of Java 8

This lambda expression exploits the Iterable functional interface, providing a custom iterator() method.

Streams: Breaking the stereotype of functional programming

Java 8 streams stand for a functional approach to processing collections. They make conversions, especially from primitive to boxed types, tasty!

Elegant code FTW

Streams and lambdas push you to write expressive, readable, and succinct codes. Say hello to modern Java development practices.

Don't Forget!

Efficiency isn't just a Word, but Practice

While whipping up solutions, efficiency should be in your ingredient list. Avoid bloating codebase or degrading performance with unnecessary operations.

UnsupportedOperationException is NOT your BFF

Handle UnsupportedOperationException while converting to modifiable collections. Not all Iterables play nice with the remove() operation.

Clear Explanations: A Must-Have

When dealing with solutions like Guava or Java 8 features, it's important to give clarity a front seat. Only when they're well-explained, they're well-received.