skip to content

Iterable & Collection Interfaces

Iterable enables the for-each loop, Collection adds the bulk operations and toArray conversions, and the families split into List, Set and Queue. The detail interviewers like is that Map is not a Collection.

part ofJavaoverview, primer and where to startread it →
on this pageshow

questions

5

What is the Iterable interface in Java, and how does it enable the for-each loop?

level: juniorimportance: must knowfreq 70%

answer

  1. Iterable -> iterator() -> Iterator(hasNext/next)
  2. for-each is compiler sugar
  3. forEach + spliterator default methods (Java 8)
  4. Map is NOT Iterable - use entrySet/keySet/values
  5. arrays work in for-each but aren't Iterable

basics

~20 s

Iterable is an interface with one main method, iterator(), that returns an Iterator. Any class that implements Iterable can be used in a for-each loop, because the compiler turns the loop into calls to iterator(), hasNext(), and next().

solid answer

~40 s

Iterable<T> is the root interface that makes an object loopable. Its key method is iterator(), which returns an Iterator<T> exposing hasNext() and next() (plus an optional remove()). The enhanced for-each loop (for (T x : things)) is pure syntactic sugar: the compiler rewrites it into obtaining an Iterator via iterator() and looping while hasNext() calling next(). So any type implementing Iterable - all Collections, plus arrays via a special case - works with for-each. Iterable also adds default methods forEach(Consumer) and spliterator() (for streams/parallelism). Because Map is not Iterable, you can't for-each a Map directly; you iterate its entrySet(), keySet(), or values() views instead.

go deeper

for a junior

Knows Iterable lets a class be used in a for-each loop and that iterator() returns an Iterator with hasNext()/next().

for a middle

Explains that for-each is compiler sugar desugared into iterator calls, knows the Java 8 default methods (forEach, spliterator), and that Map is not Iterable.

for a senior

Can implement a custom Iterable cleanly, explains the arrays-are-special-cased detail, and relates spliterator() to streams/parallelism.

for a principal

Reasons about Iterable as a design seam (lazy/infinite sequences, fail-fast semantics, spliterator characteristics for parallel performance) and when to expose Iterable vs Stream in a public API.

## What problem this solves Before Java 5 (2004), looping over a collection meant manually grabbing an iterator and calling methods in a `while` loop, or indexing an array with a counter. That is verbose and error-prone. Java introduced the **enhanced for loop** (a.k.a. **for-each**) and a tiny interface, **`Iterable`**, to make any object loopable with clean syntax. ## The `Iterable` interface `java.lang.Iterable<T>` is one of the simplest interfaces in the JDK. `T` is a **type parameter** (a placeholder for the element type, e.g. `String`). Its essential member is: ```java Iterator<T> iterator(); ``` An **`Iterator<T>`** is a separate object that walks a sequence one element at a time. Its core methods are: - `boolean hasNext()` - is there another element? - `T next()` - return the next element and advance; throws `NoSuchElementException` if there isn't one. - `default void remove()` - optionally remove the last element returned (may throw `UnsupportedOperationException`). `Iterable` also has two **default methods** (methods with a body provided by the interface itself, added in Java 8): - `forEach(Consumer<? super T> action)` - run the action on each element. - `spliterator()` - returns a `Spliterator`, the splittable iterator that backs streams and parallelism. ## How for-each is desugared The for-each loop is **syntactic sugar**: the compiler rewrites it into plain iterator calls. This: ```java for (String s : list) { use(s); } ``` becomes essentially: ```java for (Iterator<String> it = list.iterator(); it.hasNext(); ) { String s = it.next(); use(s); } ``` That is why **anything** that implements `Iterable` can be used with for-each. Arrays are a special case: the language supports for-each over arrays directly (arrays are not `Iterable`), and the compiler uses an index-based loop for them. ## Where it sits in the hierarchy `Iterable` is the **super-interface of `Collection`**. So `List`, `Set`, and `Queue` are all `Iterable` (they extend `Collection`, which extends `Iterable`). **`Map` is NOT `Iterable`** - you cannot for-each a `Map` directly; you loop over one of its **views**: `map.entrySet()`, `map.keySet()`, or `map.values()`, each of which IS iterable. ## Implementing your own To make your own class loopable, implement `Iterable<T>` and return an `Iterator<T>`: ```java class Range implements Iterable<Integer> { private final int from, to; Range(int from, int to) { this.from = from; this.to = to; } public Iterator<Integer> iterator() { return new Iterator<>() { int cur = from; public boolean hasNext() { return cur < to; } public Integer next() { return cur++; } }; } } ``` Now `for (int i : new Range(0, 5))` works. ## Key takeaways - `Iterable` = "can be iterated"; it returns an `Iterator`. - for-each is compiler sugar over `iterator()/hasNext()/next()`. - All `Collection`s are `Iterable`; `Map` is not (use its views).

  • Why can't you write for (var entry : myMap) directly?
    Because Map does not implement Iterable. You must iterate a view: for (var e : myMap.entrySet()) gives Map.Entry objects with getKey()/getValue().
  • What's the difference between Iterable and Iterator?
    Iterable is the collection that can produce a cursor; Iterator is the cursor itself with hasNext()/next(). Iterable.iterator() creates a fresh Iterator each call.

saying these in an interview costs you the question

  • Saying for-each works via reflection or magic - it is plain compiler-generated iterator calls
  • Claiming Map implements Iterable
  • Thinking arrays implement Iterable (they don't; the language special-cases them)
  • Confusing Iterable (the collection) with Iterator (the cursor)

context

open as a page

Distinguish the List, Set, Queue, and Map interfaces in the Java Collections Framework. Which is not a Collection, and why?

level: juniorimportance: must knowfreq 80%

basics

~20 s

List is an ordered sequence that allows duplicates and index access. Set holds unique elements. Queue orders elements for processing (usually FIFO). Map stores key-to-value pairs. Map is not a Collection because it deals with pairs, not single elements.

open as a page

What are the Collection bulk operations (addAll, removeAll, retainAll, containsAll, clear), and what set-like semantics do they implement?

level: middleimportance: should knowfreq 60%

basics

~20 s

They operate on whole collections at once: addAll adds everything from another collection (union), removeAll deletes everything also in another (difference), retainAll keeps only what's in another (intersection), containsAll checks if all elements are present (subset), and clear empties the collection.

open as a page

Explain Collection.toArray() and toArray(T[]). Why does the no-arg version return Object[], and what is the correct way to call the typed overload?

level: middleimportance: should knowfreq 55%

basics

~20 s

toArray() returns an Object[] because the collection doesn't know its element type at runtime (type erasure). toArray(T[]) returns a properly typed array; the modern idiom is list.toArray(new String[0]), and Java 11 added the cleaner list.toArray(String[]::new).

open as a page

From an API-design standpoint, why is Iterable separate from Collection, and why did the designers keep Map outside the Collection hierarchy? What does this teach about interface segregation?

level: principalimportance: nice to knowfreq 30%

basics

~20 s

Iterable is split out so anything traversable - not just collections - can be used in for-each (streams sources, lazy/infinite sequences, custom cursors). Map is kept separate because it stores pairs, not single elements, so it can't honestly implement the single-element Collection contract.

open as a page