2013-07-03 11 views
5

Czy istnieje idiom Java dla parowania iteracyjnego przez elementy sortowanego Collection? Rozumiem przez to, że każda iteracja ma dostęp do jednego elementu kolekcji i następnego elementu kolekcji?Idiom dla iteracji parami poprzez sortowaną kolekcję

Dla posortowanych List s (i tablic), można to zrobić za pomocą indeksu w kolekcji:

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); 
} 

ale co SortedSet? (dla SortedMap można użyć jego entrySet(), co jest odpowiednikiem przypadku SortedSet).


Tak więc, na przykład, jeśli sortowane zestaw zawierał wartości {1, 2, 3, 4} iteracje byłoby pary (1, 2), (2, 3), (3 , 4), w tej kolejności.

Odpowiedz

3

Można po prostu wdrożyć go w następujący sposób (i zastosować podobną strategię wobec innych zbiorów):

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

Wierzę, że twoja sugestia iteruje tylko przez połowę par, ponieważ każda iteracja rozwija się o 2 elementy. – Raedwald

+0

@Raedwald Ten przejdzie (1,2) (3,4) ... tak jak wskazałeś w pytaniu. – allprog

+0

Nie, spójrz na przykład, który dałem dla 'List'. – Raedwald

0

Dla Set s (i innych nie-do indeksowania zbiorów) będą potrzebne do korzystania z ich Iterator s jako zwrócony przez metodę iterator() z 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; 
} 

Można zrobić to samo dla Map s , używając Iterator s. entrySet().


Teraz rozumiem twoje pytanie lepiej, można też spróbować:

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

Wierzę, że twoja sugestia iteruje tylko przez połowę par, ponieważ każda iteracja rozwija się o 2 elementy. – Raedwald

+0

@Raedwald Tak, masz rację, źle zrozumiałem twój przykład. Powinien być już ustawiony. Dodałem też inną alternatywę, teraz, gdy rozumiem, co naprawdę próbujesz zrobić. – arshajii

1

Napisz implementację Iteratora, np. (Tylko odpisywania czubek mojej głowy, więc kod może nie działać jak jest)

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); 
      } 
     } 
    } 
} 

I prawdopodobnie nie masz odpowiednich typów dokładnie, ale „iterable” metoda sprawia, że ​​jest łatwy w użyciu w konstrukcji foreach :

for(List<String> pair : PairwiseIterator.iterable(orderedSetOfStrings)) { 
    // ... do what you need to ... 
} 
Powiązane problemy