Possible Duplicate:
Why is Java's Iterator not an Iterable?
We all know java's extended for loop:
List<X> list = ...
for(X x : list) { ... }
What I need is:
Iterator<X> listIterator = ...
for(X x : listIterator){ ... }
Java does not allow this. I was wondering if there's a good reason why the specification does not support this.
Here's my usecase:
I'm writing a reader for a kind of file format. Such a file contains entries that are to be read. For the sake of the example assume that I'm trying to reinvent BufferedReader and my elements are Strings.
I'm quite unhappy with the API style of the original BufferedReader which forces me to write ugly code like:
for(String line = reader.readLine(); line != null; line = reader.readLine(){
...
}
I'd rather have something nice like
for(String line : reader){
...
}
Of course I can make my BufferedReader implement Iterable<String>. But this implies that there is a iterator() method that might be called several times. Since I cannot seek in the file, I cannot really support multiple parallel iterators.
Having my BufferedReader implement Iterator<String> instead of Iterable<String> seems far more reasonable. But then I can't use the for statement :-(
Because the contract for the foreach loop is to iterate over every element. If it was allowed to just take an Iterator you could give it a half-consumed Iterator and it wouldn't know the difference.
Set<String> set = new HashSet(Arrays.asList(new String [] {"One", "Two", "Three"}));
Iterator i = set.iterator();
// Consume the first.
String first = i.next();
for ( String s : i ) { // Error here.
}
I accept that it would make things easier but it could also introduce some serious bugs because you wont know you have covered all entries in the collection.
// Works fine because Set is Iterable and the contract is satisfied
// that this will iterate over <b>all</b> of the entries.
for ( String s : set ) {
}
You can always hack it around by making a transient Iterable. I cant test this right now but something like:
for ( String s : new Iterable {
public iterator<String> () {
return set.iterator ();
}
} ) {
}
Cumbersome but it should work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With