Java现在有一种方便的方式来预测集合,例如。
for (MyClass c : aCollection) {
...
}
是否有类似优雅的东西来预告迭代器或我坚持:
for (;it.hasNext();) {
MyClass c = it.next();
...
}
更新:对于那些发现这个奇怪问题的人来说,我已经习惯了Python
for x in xs :
f(x)
无论xs是集合还是迭代器(甚至是生成器),都有效。我有点惊讶于Java并没有像这样工作。
我实现了一个库,我将迭代器返回到某些内部集合而不是集合本身。但我现在担心这会迫使我的图书馆用户使用比foreach更老/更丑的遍历方式。如果人们习惯使用foreach构造,这是否有效地弃用了迭代器?
答案 0 :(得分:4)
嗯,除了一个特殊的野兽阵列,"扩展为"你在这里使用的循环只是实现Iterable
的类的结果。此接口仅提供一种to return an... Iterator
的方法。
这意味着如果您使用代码编写:
for (final Foo foo: someInstanceImplementingIterableOfFoo) {
doSomethingWith(foo);
}
它实际上相当于:
final Iterator<Foo> iterator = someInstanceImplementingIterableOfFoo.iterator();
Foo foo;
while (iterator.hasNext()) {
foo = iterator.next();
doSomethingWith(foo);
}
所以,答案真的不是,没有优雅的方式......
即使您使用Java 8.它已在Iterator
上添加了forEachRemaining()
。
或者只是创建一个实用程序类:
public final class IteratorWrap<T>
implements Iterable<T>
{
private final Iterator<T> iterator;
public static <X> IteratorWrap<X> wrap(final Iterator<X> iterator)
{
return new IteratorWrap<>(iterator);
}
private IteratorWrap(final Iterator<T> iterator)
{
this.iterator = Objects.requireNonNull(iterator);
}
@Override
public Iterator<T> iterator()
{
return iterator;
}
}
在代码中,您只需:
for (final Foo foo: IteratorWrap.wrap(iteratorOfX))
doSomethingWith(foo);
答案 1 :(得分:3)
好吧,既然你想要一些现代的东西,你可以使用Java 8
Iterator<String> names = Arrays.asList("one","two","three").iterator();
for(String name : (Iterable<String>) () -> names) {
System.out.println(name);
}
由于for循环需要一个Iterable Object,使用这种技术,你可以使用lambda表达式从Iterable
中提供Iterator
。
正如另一个答案中的fge所提到的,这相当于使用方法引用的以下Java 8表达式并避免创建Iterable:
names.forEachRemaining(System.out::println);
因此,您可以将逻辑打包到Consumer
并解决问题。
答案 2 :(得分:1)
Java的“增强”for
循环要求要迭代的目标必须实现Iterable
。但是如果你只有一个Iterator
,它没有实现Iterable
,那么就没有内置的方法可以使用Iterator
作为Java中foreach循环的目标。
如果您不能使用Java 8,则可以创建一个包装Iterator
,实现Iterable
的适配器类,并在iterator()
方法中返回包装的迭代器。
class IterableIterator<T> implements Iterable<T>
{
private Iterator<T> iterator;
public IterableIterator(Iterator<T> iterator)
{
this.iterator = iterator;
}
@Override
public Iterator<T> iterator()
{
return iterator;
}
}
然后,如果您有Iterator
,则可以像这样使用它:
Iterator<MyClass> itr = getIteratorSomehow();
for (MyClass obj : new IterableIterator<MyClass>(itr))
{
// ...
}
答案 3 :(得分:0)
Iterator<String> names = Arrays.asList("one", "two", "three").iterator();
String foo;
while((foo= Iterators.getNext(names, null))!=null){
System.out.println(foo);
}