我们都知道java的扩展for
循环:
List<X> list = ...
for(X x : list) { ... }
我需要的是:
Iterator<X> listIterator = ...
for(X x : listIterator){ ... }
Java不允许这样做。 我想知道规范是否支持此是否有充分理由。
这是我的用例:
我正在为一种文件格式编写阅读器。这样的文件包含要读取的条目。为了这个例子,假设我正在尝试重新发明BufferedReader,我的元素是字符串。
我对原始BufferedReader
的API样式非常不满,这迫使我编写丑陋的代码,如:
for(String line = reader.readLine(); line != null; line = reader.readLine(){
...
}
我宁愿拥有像
这样的好东西for(String line : reader){
...
}
当然,我可以制作BufferedReader
工具Iterable<String>
。但这意味着可能会多次调用iterator()
方法。由于我无法在文件中查找,因此我无法真正支持多个并行迭代器。
让我的BufferedReader
工具Iterator<String>
代替Iterable<String>
似乎更合理。但后来我不能使用for
语句: - (
答案 0 :(得分:1)
当然,您可以支持多个并行迭代器。您可以多次打开该文件。
class BufferedReader() implements Iterable<String> {
String fileName;
InputStreamReader in;
public BufferedReader(String fileName) {
this.fileName = fileName;
in = new InputStreamReader(new FileInputStream(fileName));
}
public Iterator<String> iterator() {
return new Iterator<String>() {
BufferedReader in = new BufferedReader(fileName);
String nextLine = in.readLine();
public boolean hasNext() {
return nextLine != null;
}
public String next() {
String str = nextLine;
nextLine = in.readLine();
return str;
}
}
}
}
答案 1 :(得分:1)
因为foreach
循环的合同是迭代每个元素。如果只允许Iterator
,你就可以给它消耗一半Iterator
而且它不会知道差异。
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.
}
我接受它会让事情变得更容易,但它也会引入一些严重的错误,因为你不知道你已经涵盖了集合中的所有条目。
// 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 ) {
}
你可以通过短暂的Iterable
来破解它。我现在无法测试这个,但是像:
for ( String s : new Iterable {
public iterator<String> () {
return set.iterator ();
}
} ) {
}
虽然很麻烦,但应该可以。