2012-02-08 4 views
12

में एकाधिक पुनरावृत्तियों में शामिल हों क्या कोई जावा में एकाधिक पुनरावृत्तियों में शामिल होने के बारे में जानता है? समाधान जो मैंने पहले एक इटरेटर के माध्यम से फिर से पाया, और उसके बाद अगले स्थान पर चला गया। हालांकि, मैं जो चाहता हूं वह तब होता है जब अगला() कहा जाता है, यह पहले पहले इटरेटर से पहला तत्व देता है। अगली बार जब अगला() कहा जाता है, तो यह दूसरे पुनरावर्तक से पहला तत्व देता है, और इसी तरह।जावा

धन्यवाद

+0

एकाधिक iterators:

आप एक यौगिक iterator उपयोग करने के लिए, की तरह कुछ की जरूरत है? – kosa

+2

यिक्स: http://stackoverflow.com/questions/3610261/is-it-possible-to-merge-iterators-in-java –

+0

@RobertPeters हाँ एक डुप्ली की तरह दिखता है। flyfromchina, क्या आप इस बात का एक उदाहरण पोस्ट कर सकते हैं कि आप प्रश्न को स्पष्ट करना चाहते हैं? – daveslab

उत्तर

10

का उपयोग Guava'sAbstractIterator सादगी के लिए:

final List<Iterator<E>> theIterators; 
return new AbstractIterator<E>() { 
    private Queue<Iterator<E>> queue = new LinkedList<Iterator<E>>(theIterators); 
    @Override protected E computeNext() { 
    while(!queue.isEmpty()) { 
     Iterator<E> topIter = queue.poll(); 
     if(topIter.hasNext()) { 
     E result = topIter.next(); 
     queue.offer(topIter); 
     return result; 
     } 
    } 
    return endOfData(); 
    } 
}; 

यह आपको वांछित "interleaved" आदेश दे देंगे, यह काफी स्मार्ट संग्रह विभिन्न आकारों होने से निपटने के लिए है, और यह काफी कॉम्पैक्ट है। आप सच में, सच एक और तृतीय-पक्ष लाइब्रेरी को बर्दाश्त नहीं कर सकते हैं (आप यह मानकर कि आप जावा पर हैं 6 + गति के लिए LinkedList के स्थान पर ArrayDeque उपयोग कर सकते हैं।)

, आप कम या ज्यादा कर सकते हैं कुछ अतिरिक्त काम करते हैं, तो जैसे के साथ एक ही बात:

return new Iterator<E>() { 
    private Queue<Iterator<E>> queue = new LinkedList<Iterator<E>>(theIterators); 
    public boolean hasNext() { 
    // If this returns true, the head of the queue will have a next element 
    while(!queue.isEmpty()) { 
     if(queue.peek().hasNext()) { 
     return true; 
     } 
     queue.poll(); 
    } 
    return false; 
    } 
    public E next() { 
    if(!hasNext()) throw new NoSuchElementException(); 
    Iterator<E> iter = queue.poll(); 
    E result = iter.next(); 
    queue.offer(iter); 
    return result; 
    } 
    public void remove() { throw new UnsupportedOperationException(); } 
}; 

संदर्भ के लिए, "iter1 के सभी, iter2 के सभी, आदि" व्यवहार भी Iterators.concat(Iterator<Iterator>) और उसके भार के उपयोग कर प्राप्त किया जा सकता है।

-1

सरल दृष्टिकोण

for(Type1 t1: collection1) 
    for(Type2 t2: collection2) 

अगर आप क्या चाहते हैं यह एक संग्रह के बीच में शामिल होने के प्रदर्शन करने के लिए काम करेगा।

यदि आप दो संग्रह दोहराना चाहते हैं तो मैं केवल दो लूप का उपयोग करता हूं या दोनों के साथ संग्रह बनाउंगा।

for(Type t1: collection1) 
    process(t1); 

for(Type t2: collection2) 
    process(t2); 

यदि आप Iterators को अंतःस्थापित करना चाहते हैं तो आप एक सरणी का उपयोग कर सकते हैं।

Iterator[] iters = { iter1, iter2, ... }; 
boolean finished; 
do { 
    finished = true; 
    for(Iterator it: iters) { 
    if (it.hasNext()) { 
     Object obj = it.next(); 
     // process 
     finished = false; 
    } 
    } 
} while(!finished); 
+1

हमम मुझे लगता है कि वह प्रभावी ढंग से Coll1.get (0), Coll2.get (0), Coll1.get (1), Coll2.get (1) - यानी interleaved, nested – Bohemian

+5

नहीं है मुझे नहीं लगता कि यह क्या करेगा अनुरोध किया, है ना? –

+0

यह अनावश्यक रूप से नहीं चलेंगे? टी 1 में हर आइटम के लिए, टी 2 में सभी आइटम ?? – noMAD

3

ऐसा लगता है कि आप इंटरलीविंग चाहते हैं। कुछ इस तरह - पूरी तरह से अपरीक्षित ...

public class InterleavingIterable<E> implements Iterable<E> { 

    private final Iterable<? extends E> first; 
    private final Iterable<? extends E> second; 

    public InterleavingIterable(Iterable<? extends E> first, 
           Iterable<? extends E> second) { 
     this.first = first; 
     this.second = second; 
    } 

    public Iterator<E> iterator() { 
     return new InterleavingIterator<E>(first.iterator(), 
              second.iterator()); 
    } 

    private static class InterleavingIterator<E> implements Iterator<E> { 

     private Iterator<? extends E> next; 
     private Iterator<? extends E> current; 

     private InterleavingIterator(Iterator<? extends E> first, 
            Iterator<? extends E> second) { 
      next = first; 
      current = second; 
     } 

     public boolean hasNext() { 
      return next.hasNext() || (current != null && current.hasNext()); 
     } 

     public E next() throws NoSuchElementException { 
      if (next.hasNext()) { 
       E ret = next.next(); 
       if (current != null) { 
        Iterator<? extends E> tmp = current; 
        current = next; 
        next = tmp; 
       } 
       return ret; 
      } else { 
       // Nothing left in next... check "current" 
       if (current == null || !current.hasNext()) { 
        throw new NoSuchElementException(); 
       } 
       next = current; 
       current = null; 
       return current.next(); 
      } 
     } 

     public void remove() { 
      throw new UnsupportedOperationException(); 
     } 
    } 
} 
0

संपादित करें: ओह, आपके सवाल का गलत मतलब निकाला। तुम वास्तव में, एक इंटरलिविंग इटरेटर जरूरत है एक यौगिक इटरेटर के बजाय:

class InterleavingIterator<T> implements Iterator<T> { 

    private final Iterator<T> internalIter; 

    public InterleavingIterator(final Iterator<T>... iterators) { 
     final LinkedList<Iterator<T>> iteratorQueue = new LinkedList<Iterator<T>>(); 
     for (final Iterator<T> loopIter : iterators) { 
      if (loopIter.hasNext()) { 
       iteratorQueue.push(loopIter); 
      } 
     } 

     // create the interleaving 
     final LinkedList<T> internalList = new LinkedList<T>(); 
     while (!iteratorQueue.isEmpty()) { 
      final Iterator<T> loopIter = iteratorQueue.pop(); 
      internalList.add(loopIter.next()); 
      if (loopIter.hasNext()) { 
       iteratorQueue.push(loopIter); 
      } 
     } 
     internalIter = internalList.iterator(); 
    } 

    public boolean hasNext() { 
     return internalIter.hasNext(); 
    } 

    public T next() { 
     return internalIter.next(); 
    } 

    public void remove() { 
     throw new UnsupportedOperationException("remove() unsupported"); 
    } 
} 

समाप्ति संपादित करें। एक ही संग्रह या अलग संग्रह से प्रत्येक इटरेटर को

import java.util.Collections; 
import java.util.Iterator; 
import java.util.LinkedList; 

public class CompoundIterator<T> implements Iterator<T> { 

    private final LinkedList<Iterator<T>> iteratorQueue; 
    private Iterator<T> current; 

    public CompoundIterator(final Iterator<T>... iterators) { 
     this.iteratorQueue = new LinkedList<Iterator<T>>(); 
     for (final Iterator<T> iterator : iterators) { 
      iteratorQueue.push(iterator); 
     } 
     current = Collections.<T>emptyList().iterator(); 
    } 

    public boolean hasNext() { 
     final boolean curHasNext = current.hasNext(); 
     if (!curHasNext && !iteratorQueue.isEmpty()) { 
      current = iteratorQueue.pop(); 
      return current.hasNext(); 
     } else { 
      return curHasNext; 
     } 
    } 

    public T next() { 
     if (current.hasNext()) { 
      return current.next(); 
     } 
     if (!iteratorQueue.isEmpty()) { 
      current = iteratorQueue.pop(); 
     } 
     return current.next(); 
    } 

    public void remove() { 
     throw new UnsupportedOperationException("remove() unsupported"); 
    } 
}