2013-07-03 52 views
5

是否存在Java成語,用於通過排序的Collection的元素進行成對迭代?我的意思是說,每次迭代都可以訪問集合中的一個元素和集合的下一個元素?通過已排序集合進行成對迭代的習語

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

對於分類List S(和數組),它可以使用索引到集合做些什麼呢? (對於SortedMap,您可以使用entrySet(),相當於SortedSet的情況)。


因此,舉例來說,如果您的有序集合中包含的值{1,2,3,4},迭代將是對(1,2),(2,3),(3 ,4)。

回答

3

你可以簡單地實現它通過以下方式(以及對其他收藏品適用類似的策略):

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

     thing1 = thing2; 
    } 
} 
+0

我相信你的建議只通過一半對迭代,因爲每次迭代都會提前2個元素。 – Raedwald

+0

@Raedwald就像你在問題中指出的那樣,這個人正在通過(1,2)(3,4)......。 – allprog

+0

不,看看我給List列出的例子。 – Raedwald

0

Set S(和其它非可轉位的集合),您將需要使用他們Iterator s數iterator()方法Collection爲退貨:

Iterator<Thing> 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; 
} 

您可以Map就做相同,使用entrySet()Iterator s。


現在,我明白你的問題好,你也可以試試這個:

Iterator<Thing> 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); 
} 
+0

我相信你的建議只反映了一半,因爲每次迭代都會提前2個元素。 – Raedwald

+0

@Raedwald是的,你錯了,我誤解了你的例子。現在應該全部設置。我還增加了另一種選擇,現在我明白你真的想要做什麼。 – arshajii

1

編寫Iterator的實現,例如(只是寫了我的頭頂部,所以代碼可能無法正常工作,是)

public class PairwiseIterator<T> implements Iterator<List<T>> { 
    private final Iterator<T> elements; 
    private T last; 

    public PairwiseIterator(Collection<T> elements) { 
     this.elements = elements.iterator(); 
     last = elements.hasNext() ? elements.next() : null; 
    } 

    @Override 
    public boolean hasNext() { 
     return elements.hasNext(); 
    } 

    @Override 
    public List<T> next() { 
     List<T> 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 <U> Iterable<List<U>> iterable(final Collection<U> elements) { 
     return new Iterable() { 
      public Iterator<U> iterator() { 
       return new PairwiseIterator(elements); 
      } 
     } 
    } 
} 

我可能沒有類型完全正確,但「迭代」的方法可以很容易在的foreach構造使用:

for(List<String> pair : PairwiseIterator.iterable(orderedSetOfStrings)) { 
    // ... do what you need to ... 
} 
相關問題