Idiom for pairwise iteration through a sorted collection

前端 未结 5 730
误落风尘
误落风尘 2021-01-03 02:54

Is there a Java idiom for pairwise iteration through the elements of a sorted Collection? By that I mean that each iteration has access to one element of the co

相关标签:
5条回答
  • 2021-01-03 03:12

    For Sets (and other non-indexable collections) you will need to use their Iterators as returned by the iterator() method of 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;
    }
    

    You can do the same for Maps, using the Iterator of their entrySet()s.


    Now that I understand your question better, you could also try this:

    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 讨论(0)
  • 2021-01-03 03:20

    Write an implementation of Iterator, e.g. (just writing off the top of my head, so code may not work as is)

    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 probably don't have the types exactly right, but the 'iterable' method makes it easy to use in foreach constructs:

    for(List<String> pair : PairwiseIterator.iterable(orderedSetOfStrings)) {
        // ... do what you need to ...
    }
    
    0 讨论(0)
  • 2021-01-03 03:27

    You can simply implement it the following way (and apply similar strategy towards other collections):

    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;
    }
    
    0 讨论(0)
  • 2021-01-03 03:29

    Guava offers a PeekingIterator which can be used for this:

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

    When the loop code becomes more complex, the benefit becomes more evident, maybe.

    0 讨论(0)
  • 2021-01-03 03:35
    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 讨论(0)
提交回复
热议问题