5

sorted の要素をペアごとに反復するための Java イディオムはありCollectionますか? つまり、各反復はコレクションの 1 つの要素とコレクションの次の要素にアクセスできるということですか?

ソートされたLists (および配列) の場合、コレクションへのインデックスを使用して実行できます。

 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) の順序で行われます。 .

4

5 に答える 5

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;
    }
}
于 2013-07-03T16:16:54.560 に答える
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;
}
于 2013-07-03T21:02:01.340 に答える
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 ...
}
于 2014-07-09T18:20:52.957 に答える
0

s (およびその他のインデックス化できないコレクション) の場合、次のメソッドによって返される sSetを使用する必要があります。Iteratoriterator()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の を使用して、Iteratorについても同じことができますentrySet()


あなたの質問をよりよく理解したので、これを試すこともできます:

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);
}
于 2013-07-03T16:17:07.593 に答える
0

Guava は、これに使用できる PeekingIterator を提供します。

PeekingIterator<Thing> iter = 
    Iterators.peekingIterator(set.iterator());
while (iter.hasNext()) {
    final Thing thing1 = iter.next();
   if (iter.hasNext()) { // don't forget this one
        operateOnAdjacentPair(thing1, iter.peek());
    }
}

ループ コードがより複雑になると、そのメリットがより明確になる可能性があります。

于 2019-06-11T09:02:40.217 に答える