有没有办法在Java中使用Iterator?

时间:2015-01-22 00:34:57

标签: java iterator

Java现在有一种方便的方式来预测集合,例如。

for (MyClass c : aCollection) {
...
}

是否有类似优雅的东西来预告迭代器或我坚持:

for (;it.hasNext();) {
   MyClass c = it.next();
   ...
}

更新:对于那些发现这个奇怪问题的人来说,我已经习惯了Python

for x in xs :
  f(x)
无论xs是集合还是迭代器(甚至是生成器),

都有效。我有点惊讶于Java并没有像这样工作。

我实现了一个库,我将迭代器返回到某些内部集合而不是集合本身。但我现在担心这会迫使我的图书馆用户使用比foreach更老/更丑的遍历方式。如果人们习惯使用foreach构造,这是否有效地弃用了迭代器?

4 个答案:

答案 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);
    }