简化在Java中编写自定义迭代器的过程

fre*_*low 4 c# java collections iterator yield-return

在Java中为自定义集合编写迭代器非常复杂,因为您不必编写提供一个元素的直接代码,而是必须编写状态机:

public class CustomCollection<T> implements Iterable<T>
{
    private T[] data;
    private int size;

    @Override
    public Iterator<T> iterator()
    {
        return new Iterator<T>()
        {
            private int cursor = 0;

            @Override
            public boolean hasNext()
            {
                return cursor < size;
            }

            @Override
            public T next()
            {
                return data[cursor++];
            }

            @Override
            public void remove()
            {
                throw new UnsupportedOperationException();
            }
        };
    }
    // ...
}
Run Code Online (Sandbox Code Playgroud)

对于比数组列表或链表更复杂的集合,正确获取这些状态机是一项艰巨的任务.事实上,C#设计团队认为编写自定义迭代器足够复杂,可以引入特殊的语言支持(yield return),让编译器构建状态机.

就像yield return下一个版本的Java一样?或者,在Java中编写自己的迭代器时,是否存在使我的生活更轻松的库解决方案?

Col*_*inD 5

不,Java没有类似的东西yield.就库而言,Guava有许多有用的类可以使某些类型的迭代器易于编写:

  • AbstractIterator只需要你实现一个T computeNext()方法.
  • AbstractLinkedIterator要求你实施T computeNext(T previous).

AbstractIterator 可用于此如下:

return new AbstractIterator<T>() {
  private int index = 0;

  protected T computeNext() {
    return index == size ? endOfData() : data[index++];
  }
};
Run Code Online (Sandbox Code Playgroud)

您也可以Arrays.asList像Amir建议的那样使用,甚至可以这样做:

private final List<T> listView = new AbstractList<T>() {
  public int size() {
    return data.length;
  }

  public T get(int index) {
    return data[index];
  }
};

public Iterator<T> iterator() {
  return listView.iterator();
}
Run Code Online (Sandbox Code Playgroud)