2014-09-02 6 views
10

मैं सोच रहा था कि स्ट्रीम में सभी सूचियों के तत्वों वाले संग्रह में सूचियों की धारा से प्राप्त करने का पसंदीदा तरीका है या नहीं। मैं दो तरीकों से वहाँ पहुँचने के लिए के बारे में सोच सकते हैं:क्या कोई पसंदीदा तरीका सूचियों की एक सूची को एक फ्लैट सूची में एकत्रित करता है?

final Stream<List<Integer>> stream = Stream.empty(); 
final List<Integer> one = stream.collect(ArrayList::new, ArrayList::addAll, ArrayList::addAll); 
final List<Integer> two = stream.flatMap(List::stream).collect(Collectors.toList()); 

दूसरा विकल्प ज्यादा मेरे लिए अच्छे है, लेकिन मुझे लगता है कि पहले एक समानांतर धाराओं में अधिक सक्षम है। क्या दो तरीकों में से एक के खिलाफ या इसके खिलाफ और तर्क हैं?

उत्तर

9

मुख्य अंतर यह है कि flatMap एक intermediate operation. है जबकि collectterminal operation है।

तो flatMapएक ही रास्ता चपटा धारा आइटम पर कार्रवाई करने के लिए यदि आप collect के अलावा अन्य संचालन करने के लिए तुरंत ing चाहते हैं।

आगे collect(ArrayList::new, ArrayList::addAll, ArrayList::addAll) इस तथ्य को पढ़ने के लिए बहुत मुश्किल है कि आपके पास दो समान विधि संदर्भ ArrayList::addAll पूरी तरह से अलग अर्थशास्त्र के साथ हैं।

समांतर प्रसंस्करण के संबंध में, आपका अनुमान गलत है। पहले व्यक्ति में समांतर प्रसंस्करण की कम क्षमता होती है क्योंकि यह ArrayList.addAll पर निर्भर करता है जो स्ट्रीम आइटम (उप-सूचियों) पर लागू होता है जिसे समानांतर उप-चरणों में विभाजित नहीं किया जा सकता है। इसके विपरीत, Collectors.toList()flatMapपर लागू किया जा सकता है उप-सूची आइटमों की समांतर प्रसंस्करण करते हैं यदि स्ट्रीम में विशेष List का सामना करना पड़ता है। लेकिन यह केवल तभी प्रासंगिक होगा यदि आपके पास बड़ी उप-सूचियों की अपेक्षाकृत छोटी धारा हो।

flatMap का एकमात्र दोष मध्यवर्ती धारा निर्माण है जो इस मामले में एक ओवरहेड जोड़ता है कि आपके पास बहुत छोटी उप-सूचियां हैं।

लेकिन आपके उदाहरण में, स्ट्रीम खाली है इसलिए इससे कोई फर्क नहीं पड़ता (scnr)।

+0

क्या आप विस्तृत कर सकते हैं, पहला संस्करण समांतर धारा में अच्छा प्रदर्शन क्यों नहीं करेगा? संग्रह के सामने इंटरमीडिएट ऑपरेशंस समानांतर में किया जा सकता है और कई एरेलीलिस्ट को संचयक फ़ंक्शन (संग्रह का दूसरा पैरामीटर) का उपयोग करके बनाए रखा जा सकता है। बाद में combiner (तीसरा पैरामीटर) का उपयोग सभी तत्वों को एक बड़े ArrayList में एकत्र करने के लिए किया जाएगा। (इस मामले में, दोनों कार्य निश्चित रूप से वही होंगे, लेकिन एक अलग तरीके से उपयोग किए जाते हैं) – muued

+1

समानांतरता ** 'स्ट्रीम' ** प्रसंस्करण के संबंध में दोनों संस्करणों में समान है, जो * बाहरी * स्ट्रीम है। लेकिन दूसरे संस्करण में फ़्लैटेड स्ट्रीम ** ** उप-सूचियों ** के तत्वों से मिलती है जो व्यवहार्य होने पर उप-सूचियों के बीच में संचालन को विभाजित करने की अनुमति देती है। यह पहले संस्करण में असंभव है। जैसा कि कहा गया है, यह केवल तभी प्रासंगिक है जब स्ट्रीम में कुछ बड़ी उप-सूचियां हों (और यदि वे आकार में भिन्न हों)। चूंकि आपके पास 'फ्लैटमैप' और 'संग्रह' के बीच मध्यवर्ती परिचालन नहीं हैं, इसलिए केवल 'संग्रह' ही प्रभावित होता है, इसलिए अंतर बहुत छोटा हो सकता है। – Holger

+0

ठीक है, अगर 'flatMap' और 'collect'' के बीच आवश्यक संचालन आवश्यक हैं तो निश्चित रूप से पहले संस्करण का उपयोग नहीं करना चाहिए। मैंने उन पर विचार नहीं किया। आपके जवाब के लिए धन्यवाद – muued

4

मुझे लगता है कि विकल्प दो का इरादा विकल्प विकल्प की तुलना में काफी स्पष्ट है। मुझे पहले कुछ के साथ क्या हो रहा था, यह काम करने में कुछ सेकंड लगे, यह "सही" नहीं दिखता है - हालांकि यह मान्य लगता है। विकल्प दो मेरे लिए अधिक स्पष्ट था।

अनिवार्य रूप से, आप जो कर रहे हैं उसका इरादा एक फ्लैटमैप है। अगर ऐसा है तो मैं addAll() का उपयोग करने के बजाय इस्तेमाल किए गए फ्लैटमैप को देखने की अपेक्षा करता हूं।

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