Friday, August 11, 2006

Read-only enhanced for loops in Java

I was just commenting on Paul Holser's blog about this small idiom using the Java enhanced for loop:

for (final T t : unmodifiable(collection)) {
    doSomethingWith(t);
}

The plumbing is simple:

public static <T> Iterable<T> unmodifiable(
        final Collection<T> c) {
    return new Iterable<T>() {
        public Iterator<T> iterator() {
            // Presuming a static decorator method
            // akin to Collections.unmodifiableCollection()
            return unmodifiableIterator(c.iterator());
        }
    };
}

Naturally, I wish Sun would add something like this to java.util.Collections, but I am sure they get many, many requests for JDK additions. Adding in a cleaned up Jakarta Collections library would help.

Another example of this sort of thing is a filterable iterator:

for (final T t : filter(collection, filter) {
    // Only works on collection elements
    // accepted by the filter.
    doSomethingWith(t);
}

Anyway, Paul has a lot of interesting ideas in store for Jaggregate 3.0.

UPDATE: An anonymous commenter made the observation that an immutable Iterable is useless in an enhanced for loop. D'oh! I should not have overlooked that point when I used the enhanced for loop in my examples. However, the read-only property is still useful when you call iterator().

5 comments:

  1. This is implemented in JGA.

    ReplyDelete
  2. What does this accomplish? Enhanced for loops don't expose the iterator, so they can't modify the collection anyway.

    ReplyDelete
  3. You know... you are right. I was thinking about Iterator and added Iterable out of habit.

    ReplyDelete
  4. Why won't the unmodifiable methods in the Collections class do what you want?

    ReplyDelete
  5. Re: Collections.unmodifiable(Collection).

    You could, of course, use that. I presented the Iterator more as example code when all you want is an Iteratable and not a full Collection interface. Less is more, as they say.

    ReplyDelete