我们可以在Java中编写我们自己的迭代器吗?

如果我有一个包含[alice, bob, abigail, charlie] ,我想编写一个迭代器,以迭代以“a”开头的元素,我可以写我自己的? 我怎样才能做到这一点 ?

当然。 迭代器只是java.util.Iterator接口的一个实现。 如果您使用java.util现有的可迭代对象(比如LinkedList ),则需要对其进行子类化并覆盖其iterator函数,以便返回自己的iterator ,或者提供一种方法来包装标准迭代器你的特殊的Iterator实例(它有更广泛的用途)等等

最好的可重用选项是实现接口Iterable并覆盖方法iterator()。

下面是一个像实现接口的类ArrayList的例子,在这个例子中你重写了方法Iterator()。

 import java.util.Iterator; public class SOList<Type> implements Iterable<Type> { private Type[] arrayList; private int currentSize; public SOList(Type[] newArray) { this.arrayList = newArray; this.currentSize = arrayList.length; } @Override public Iterator<Type> iterator() { Iterator<Type> it = new Iterator<Type>() { private int currentIndex = 0; @Override public boolean hasNext() { return currentIndex < currentSize && arrayList[currentIndex] != null; } @Override public Type next() { return arrayList[currentIndex++]; } @Override public void remove() { throw new UnsupportedOperationException(); } }; return it; } } 

该类使用generics实现了Iterable接口。 考虑到你有这个数组的元素,你将能够得到一个迭代器的实例,例如,这个实例就是“foreach”循环使用的实例。

你可以创build一个迭代器的匿名实例,而无需创buildIterator的扩展,并利用currentSize的值来validation你可以在这个数组上导航的位置(假设你创build了一个容量为10的数组,但你只有2个元素在0和1)。 实例将拥有它的所有者计数器,你需要做的就是使用hasNext()来validation当前值是否为空,next()将返回currentIndex的实例。 以下是使用此API的示例…

 public static void main(String[] args) { // create an array of type Integer Integer[] numbers = new Integer[]{1, 2, 3, 4, 5}; // create your list and hold the values. SOList<Integer> stackOverflowList = new SOList<Integer>(numbers); // Since our class SOList is an instance of Iterable, then we can use it on a foreach loop for(Integer num : stackOverflowList) { System.out.print(num); } // creating an array of Strings String[] languages = new String[]{"C", "C++", "Java", "Python", "Scala"}; // create your list and hold the values using the same list implementation. SOList<String> languagesList = new SOList<String>(languages); System.out.println(""); // Since our class SOList is an instance of Iterable, then we can use it on a foreach loop for(String lang : languagesList) { System.out.println(lang); } } // will print "12345 //C //C++ //Java //Python //Scala 

如果你愿意,你可以使用Iterator实例来迭代它:

 // navigating the iterator while (allNumbers.hasNext()) { Integer value = allNumbers.next(); if (allNumbers.hasNext()) { System.out.print(value + ", "); } else { System.out.print(value); } } // will print 1, 2, 3, 4, 5 

foreach文档位于http://download.oracle.com/javase/1,5.0/docs/guide/language/foreach.html 。 你可以看看我的个人实践的谷歌代码更完整的实施。

现在,为了得到你所需要的效果,我想你需要在Iterator中插入一个filter的概念…因为迭代器依赖于下一个值,所以很难在hasNext()上返回true,然后使用不以char“a”开头的值来过滤next()实现。 我认为你需要基于一个过滤列表来使用给定filter的值来玩弄辅助Interator。

你可以实现你自己的迭代器。 你的迭代器可以被构造来包装由List返回的Iterator,或者你可以保留一个游标并使用List的get(int index)方法。 您只需将逻辑添加到您的迭代器的下一个方法,并使用hasNext方法来考虑您的过滤标准。 你还必须决定你的迭代器是否支持删除操作。

计算阶乘的Iterable的好例子

 FactorialIterable fi = new FactorialIterable(10); Iterator<Integer> iterator = fi.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } 

Java 1.8的简称

 new FactorialIterable(5).forEach(System.out::println); 

自定义Iterable类

 public class FactorialIterable implements Iterable<Integer> { private final FactorialIteartor factorialIteartor; public FactorialIterable(Integer value) { factorialIteartor = new FactorialIteartor(value); } @Override public Iterator<Integer> iterator() { return factorialIteartor; } @Override public void forEach(Consumer<? super Integer> action) { Objects.requireNonNull(action); Integer last = 0; for (Integer t : this) { last = t; } action.accept(last); } } 

自定义Iterator类

 public class FactorialIteartor implements Iterator<Integer> { private final Integer mNumber; private Integer mPosition; private Integer mFactorial; public FactorialIteartor(Integer number) { this.mNumber = number; this.mPosition = 1; this.mFactorial = 1; } @Override public boolean hasNext() { return mPosition <= mNumber; } @Override public Integer next() { if (!hasNext()) return 0; mFactorial = mFactorial * mPosition; mPosition++; return mFactorial; } }