2014-06-05 22 views
21

मैं दो जावा -8-स्ट्रीम एक साथ फिर से शुरू करना चाहता हूं, ताकि मेरे प्रत्येक पुनरावृत्ति चरण में दो तर्क हो। ऐसा कुछ, जहां somefunctionStream<Pair<A,B>> जैसे कुछ उत्पन्न करता है।दो जावा -8-स्ट्रीम एक साथ

Stream<A> as; 
Stream<B> bs; 
somefunction (as, bs) 
    .forEach ((a, b) -> foo (a, b)); 
// or something like 
somefunction (as, bs) 
    .forEach ((Pair<A, B> abs) -> foo (abs.left(), abs.right())); 

मैं जानना चाहता हूँ, अगर जावा ऐसा ही कुछ प्रदान करता है, यद्यपि वहाँ है जावा में कोई Pair :-(यदि ऐसा कोई एपीआई-समारोह है, वहाँ simultaniously दो धाराओं पुनरावृत्ति का एक और तरीका है?

उत्तर

19
static <A, B> Stream<Pair<A, B>> zip(Stream<A> as, Stream<B> bs) 
{ 
    Iterator<A> i=as.iterator(); 
    return bs.filter(x->i.hasNext()).map(b->new Pair<>(i.next(), b)); 
} 

यह समानांतर निष्पादन की पेशकश नहीं करता है लेकिन मूल zip कार्यान्वयन भी नहीं किया गया है।

और F. Böller has pointed out के रूप में यह काम नहीं करता है अगर bs अनंत है और as नहीं है। एक समाधान है जो अनंत और परिमित धाराओं के सभी संभव संयोजनों के लिए काम करता है, एक मध्यवर्ती Iterator जो hasNext विधि के भीतर दोनों स्रोतों की जाँच करता है unavoidable¹ लगता है के लिए:

static <A, B> Stream<Pair<A,B>> zip(Stream<A> as, Stream<B> bs) { 
    Iterator<A> i1 = as.iterator(); 
    Iterator<B> i2 = bs.iterator(); 
    Iterable<Pair<A,B>> i=()->new Iterator<Pair<A,B>>() { 
     public boolean hasNext() { 
      return i1.hasNext() && i2.hasNext(); 
     } 
     public Pair<A,B> next() { 
      return new Pair<A,B>(i1.next(), i2.next()); 
     } 
    }; 
    return StreamSupport.stream(i.spliterator(), false); 
} 

आप समानांतर सक्षम ज़िप करने चाहते हैं तो आप के स्रोत पर विचार करना चाहिए Stream। जैसे आप की तरह

ArrayList<Foo> l1=new ArrayList<>(); 
ArrayList<Bar> l2=new ArrayList<>(); 
IntStream.range(0, Math.min(l1.size(), l2.size())) 
     .mapToObj(i->new Pair(l1.get(i), l2.get(i))) 
     . … 

¹ दो ArrayList रों (या किसी भी RandomAccessList) ज़िप कर सकते हैं

+0

बस पता चला कि यह समाधान बीएस के अनंत स्ट्रीम के लिए काम नहीं कर रहा है। इस मामले में यह एक अंतहीन पाश है। बी-स्ट्रीम को किसी भी तरह से सीमित किया जाना चाहिए। हालांकि, मुझे आपके उपरोक्त कोड में छोटे बदलावों के साथ समाधान नहीं मिला। लिंक किया गया उत्तर असीमित धाराओं के साथ भी काम करता प्रतीत होता है: [लिंक] (http://stackoverflow.com/a/23529010/3699131) –

+1

@F। बोल्डर: ठीक है, इसे हल करने में कोई छोटा बदलाव नहीं है। आपके द्वारा लिंक किया गया समाधान काम कर सकता है लेकिन मैं लाइसेंसिंग मुद्दों के बारे में सावधान रहने की सलाह देता हूं क्योंकि कोड बीटा जेडीके स्रोत से सी और पी किया गया है क्योंकि उत्तरदाता स्वयं ही कहता है। आपको यह भी ध्यान में रखना चाहिए कि अन्य समस्याएं हो सकती हैं क्योंकि कोड के लेखकों के पास jdk से इसे हटाने का कारण हो सकता है ... – Holger

-11

AFAIK आपकी आवश्यकता की तरह कुछ भी नहीं है लेकिन आप क्या कर सकते हैं दो धागे बनाते हैं और धाराओं को इन थ्रेडों में पास करते हैं। प्रत्येक धागा धाराओं को फिर से सक्रिय करेगा और उस पर कुछ तर्क लागू करेगा। थ्रेड सृजन जावा 8 के साथ आसान तरीका है

new Thread(
    () -> System.out.println("hello world") 
).start(); 
+0

मैं नहीं दिख रहा है, यह कैसे दो धागे के साथ संभव हो जाना चाहिए (जब तक आप एक Spliterator सीधे लागू), करने के लिए एक साथ प्रत्येक धाराओं को संसाधित करें। –

+0

इस सवाल का जवाब देते हुए, मैंने यह माना कि आपके पास पहले से ही आपकी जोड़ी कक्षा से बनाई गई दो सूचियां हैं, स्पष्ट रूप से बोलते हुए मुझे यह भी पता नहीं था कि आप अपाचे कॉमन्स जोयर क्लास का उपयोग कर रहे हैं। –

संबंधित मुद्दे