Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Java how would you write the equivalent of Iterable which could throw exceptions?

Tags:

java

exception

In java a class can implement Iterable which lets you use the foreach() statement and the iteration syntatic sugar:

for(T t:ts) ...

However, this does not allow you to throw exceptions on the construction for an Iterator. If you were iterating off a network, file, database etc it would be nice to be able to throw exceptions. Obvious candidates are java.io.InputStream, Reader and the java.nio.Channel code, but none of this can use Generics like the Iterable interface can.

Is there a common idiom or Java API for this situation?

Clarification: This is asking if there is a pattern or alternative interface for iterating for objects off a non-memory source. As responders have said, just throwing RuntimeExceptions to get around the problem is not recommended or what I was looking for.

Edit 2: Thanks to answers so far. The consensus seems to be "you can't". So can I extend the question to "What do you do in this situation, when this situation would be useful?" Just write your own interface?

like image 811
Nick Fortescue Avatar asked Jan 19 '09 08:01

Nick Fortescue


People also ask

What is iterable in Java?

The Iterable interface was introduced in JDK 1.5. It belongs to java. lang package. In general, an object Implementing Iterable allows it to be iterated. An iterable interface allows an object to be the target of enhanced for loop(for-each loop).

What does the forEach () method on Iterable do?

forEach. Performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception. Unless otherwise specified by the implementing class, actions are performed in the order of iteration (if an iteration order is specified).

What implements Iterable in Java?

An Iterable interface is defined in java. lang package and introduced with Java 5 version. An object that implements this interface allows it to be the target of the "for-each" statement. This for-each loop is used for iterating over arrays and collections.

What is the difference between for loop and Iterator in Java?

In for-each loop, we can't modify collection, it will throw a ConcurrentModificationException on the other hand with iterator we can modify collection. Modifying a collection simply means removing an element or changing content of an item stored in the collection.


1 Answers

Unfortunately you can't. There are two problems:

  • The Iterator API doesn't declare any exceptions to be thrown, so you'd have to throw RuntimeExceptions (or non-Exception throwables)
  • The enhanced for loop doesn't do anything to try to release resources at the end of the loop

This is very annoying. In C#, for instance, you can really easily write code to iterate through the lines of a text file:

public static IEnumerable<string> ReadLines(string filename)
{
    using (TextReader reader = File.OpenText(filename))
    {
        string line;
        while ( (line=reader.ReadLine()) != null)
        {
            yield return line;
        }
    }
}

Use as:

foreach (string line in ReadLines("foo.txt"))

The foreach loop calls Dispose on the IEnumerator in a finally block, which translates to "check if we need to do anything in the iterator block's finally (from the using statement)". Obviously there are no checked exceptions in C#, so that side of things isn't a problem either.

A whole (useful!) idiom is pretty much unworkable in Java due to this.

like image 149
Jon Skeet Avatar answered Oct 13 '22 15:10

Jon Skeet