成对迭代通过已排序集合的成语

是否存在通过已排序Collection的元素进行成对迭代的Java习惯用法? 我的意思是每次迭代都可以访问集合的一个元素和集合的下一个元素?

对于排序的List (和数组),可以使用集合中的索引来完成:

  final int n = list.size(); assert 2 <= n; for (int i = 0; i < n - 1; ++i) { final Thing thing1 = list.get(i); final Thing thing2 = list.get(i+1); operateOnAdjacentPair(thing1, thing2); } 

但是SortedSet怎么样? (对于SortedMap您可以使用其entrySet() ,它等同于SortedSet情况)。


因此,例如,如果您的有序集包含值{1,2,3,4},则迭代将按对象(1,2),(2,3),(3,4)按顺序进行。

您可以通过以下方式简单地实现它(并对其他集合应用类似的策略):

 Iterator iter = set.iterator(); Thing previous = iter.hasNext() ? iter.next() : null; while (iter.hasNext()) { final Thing current = iter.next(); operateOnAdjacentPair(previous, current); previous = current; } 
 Iterator thingerator = coll.iterator(); if (thingerator.hasNext()) { Thing thing1 = thingerator.next(); while (thingerator.hasNext()) { final Thing thing2 = thingerator.next(); doStuffToThings(thing1, thing2); thing1 = thing2; } } 

写一个Iterator的实现,例如(只是写下我的头顶,所以代码可能无法正常工作)

 public class PairwiseIterator implements Iterator> { private final Iterator elements; private T last; public PairwiseIterator(Collection elements) { this.elements = elements.iterator(); last = elements.hasNext() ? elements.next() : null; } @Override public boolean hasNext() { return elements.hasNext(); } @Override public List next() { List result = ImmutableList.of(last, elements.next()); last = result.get(1); return result; } @Override public void remove() { throw new UnsupportedOperationException("Remove not allowed with this iterator"); } public static  Iterable> iterable(final Collection elements) { return new Iterable() { public Iterator iterator() { return new PairwiseIterator(elements); } } } } 

我可能没有完全正确的类型,但’iterable’方法使它易于在foreach结构中使用:

 for(List pair : PairwiseIterator.iterable(orderedSetOfStrings)) { // ... do what you need to ... } 

对于Set (和其他不可索引的集合),您将需要使用它们的Collectioniterator()方法返回的iterator()

 Iterator iter = set.iterator(); Thing thing1 = iter.next(); // might want to check if this exists while (iter.hasNext()) { Thing thing2 = iter.next(); operateOnAdjacentPair(thing1, thing2); thing1 = thing2; } 

您可以使用其entrySet()IteratorMap执行相同的操作。


既然我更了解你的问题,你也可以试试这个:

 Iterator iter1 = set.iterator(), iter2 = set.iterator(); if (iter2.hasNext()) iter2.next(); // burn first element while (iter2.hasNext()) { final Thing thing1 = iter1.next(); final Thing thing2 = iter2.next(); operateOnAdjacentPair(thing1, thing2); }