2017-01-09 15 views
6

में मैंने हाल ही में जावा 8 में स्ट्रीम के बारे में सीखा और उनके साथ काम करना शुरू कर दिया। अब मैं groupingBy कलेक्टर विधि से संबंधित प्रश्न है:जावा 8 ग्रुपिंग पेक

आमतौर पर मैं नेट के साथ काम करते हैं, तो मैं तुलना में (यह जानकर वे कर रहे हैं नहीं ही) नेट IEnumerable<T> साथ जावा Stream<T>। इस तुलना के बाद, List<T> स्टोर तत्वों और विशेष Stream/IEnumerable संचालन लागू करता है। एक उदाहरण:

सी #:

elements.Where(x => x.Value == 5).ToList(); 

जावा:

elements.stream().filter(x -> x.getValue() == 5).collect(Collectors.toList()); 

दोनों उदाहरणों में, मैं एक सूची के साथ शुरू, संचालन (इस उदाहरण में एक फिल्टर) को परिभाषित करने और स्टोर करने के लिए परिणाम इकट्ठा यह (इस उदाहरण में एक नई सूची में)।

data.stream() 
    .map(...).filter(...) // Some operations 
    .collect(groupingBy(Chunk::getName, summingLong(Chunk::getValue))); 

इस क्वेरी के परिणाम एक Map<String, Long> है और मैं इस के साथ काम कर सकते हैं, लेकिन कहते हैं कि, मैं इसे भंडारण के बजाय इस डेटा के साथ आगे बढ़ना चाहते हैं कर सकते हैं:

अब मैं एक अधिक जटिल मामला मिला है। मेरे वर्तमान दृष्टिकोण तुच्छ है:

... 
    .collect(groupingBy(Chunk::getName, summingLong(Chunk::getValue))) 
    .entrySet().stream(). 
    .map(...) // Do more operations 

लेकिन इस तरह से, मैं धारा छोड़ देते हैं, एक मानचित्र में पहला परिणाम की दुकान और जारी रखने के लिए एक नई धारा को खोलें। क्या कलेक्टर के बिना समूह करने का कोई तरीका है, ताकि मैं स्ट्रीम में "रह सकूं"?

+1

चूंकि आप समूह कर रहे हैं, तो आपको बहुत से मध्यवर्ती स्टोर में जाना होगा - क्या होगा यदि आपको अंत में मूल्य के साथ स्ट्रीम की शुरुआत में मूल्य को समूहित करने की आवश्यकता है? आपको "सबकुछ" संसाधित करने की आवश्यकता होगी, इसे तब तक संग्रहित करना होगा जब तक आप सुनिश्चित न हों कि समूह के साथ कुछ और नहीं है। तो आंतरिक रूप से, जावा को (/??) चीजों को एक मानचित्र (या कुछ समान संरचना) में रखना होगा; यह खुद करने के बारे में इतना बुरा क्या है? –

+0

यह वास्तव में कोई समस्या नहीं है, मैं अपने छोटे दृष्टिकोण के साथ रह सकता हूं, लेकिन मेरे सभी अन्य धारा संचालनों में 'सूची' रखने और 'स्ट्रीम' रखने के बीच एक स्पष्ट रेखा थी। मैंने इसे खोल दिया, उस पर संचालित किया और इसे इकट्ठा किया। अब एक नक्शा है, जो एक नई धारा के लिए खोला जाता है, इसलिए मैं सोच रहा था कि क्या यह किसी अन्य दृष्टिकोण के साथ संभव है। –

+0

शायद मैं अपने .NET पृष्ठभूमि से भ्रमित हो गया। वहां आप 'IENumerable' पर कोई भी ऑपरेशन कर सकते हैं और अंत में आप अपना परिणाम' ToList', 'ToArray',' ToDictionary' या इसके ऊपर फिर से भरकर एकत्रित कर सकते हैं। –

उत्तर

4

जैसा कि एपीआई अभी है, आप इससे बच नहीं सकते हैं। ताकि आपरेशन धारा खत्म हो जाएगा

groupingBy

, एक टर्मिनल आपरेशन (यह एक स्ट्रीम वापस नहीं करता है) है।

अंतिम मानचित्र ऑपरेशन के अंदर आप जो करना चाहते हैं उसके आधार पर, आप एक कस्टम कलेक्टर बना सकते हैं जो स्ट्रीम के अंदर "रहें"; यहां तक ​​कि यदि आप के अंदर भी शायद मैप में तत्व इकट्ठा करेंगे।

+0

क्या वहां है कोई कलेक्टर ऑपरेशन जो टर्मिनल नहीं है? यदि नहीं, तो मुझे लगता है कि यह डिज़ाइन द्वारा है, इसलिए मैन्युअल रूप से एक नई स्ट्रीम खोलना बेहतर होगा, क्या मैं सही हूँ? –

+1

@lukegv nope वहाँ नहीं है; तुम सही हो। – Eugene

5

आप डाउनस्ट्रीम कलेक्टर में जो भी चाहें कर सकते हैं, जब तक आप ऑपरेशन का वर्णन Collector के रूप में कर सकते हैं। वर्तमान में, इंटरमीडिएट ऑपरेशन map, mapping कलेक्टर के समतुल्य समकक्ष है, लेकिन जावा 9 filtering और flatMapping भी जोड़ देगा (जिसे आप स्वयं जावा 8 में भी कार्यान्वित कर सकते हैं) और लगभग हर टर्मिनल ऑपरेशन के बराबर है।

बेशक

, लेनेवालों के लिए एक आंतरिक उपकरण एक ही कर स्ट्रीम संचालन की एक श्रृंखला से पूरी तरह से अलग दिखेगा ...

अगर, हालांकि, आप पूरा समूहों पर कार्रवाई करना चाहते हैं, वहाँ grouping संग्रह को पूरा करने के आसपास कोई रास्ता नहीं है प्रथम। यह एपीआई की सीमा नहीं है, लेकिन समूह के संचालन या सामान्य रूप से किसी भी ऑपरेशन के लिए अंतर्निहित है, यदि आप एक पूर्ण परिणाम संसाधित करना चाहते हैं, तो आपको पहले ऑपरेशन को पूरा करने की आवश्यकता होगी। चाहे एपीआई कैसा दिखता है, उदाहरण के बावजूद आप collectingAndThen में कलेक्टर में फॉलो-अप ऑपरेशन को छिपा सकते हैं, जैसा कि Map बनाना और पॉप्युलेट करना अपरिहार्य है, क्योंकि यह समूह समूह के रखरखाव कर रहा है।समूह Map की कुंजी और लुकअप तर्क द्वारा निर्धारित किए जाते हैं, इसलिए, उदा। एक कस्टम तुलनित्र या IdentityHashMap के साथ SortedMap का उपयोग करके, समूहांकन तर्क को पूरी तरह से बदल सकता है।