2017-07-20 4 views
6

मेरे पास एक संग्रह है जिसमें कुछ मानों के साथ सेट प्रकार का फ़ील्ड है। मुझे इन सभी मूल्यों को एकत्रित करने के लिए एक नया सेट बनाना होगा।सेट फ़ील्ड के सभी मानों को एकत्र करें

मुझे आश्चर्य है कि यह लैम्ब्डा अभिव्यक्तियों का उपयोग कर संभव है या नहीं।

Set<String> teacherId = batches.stream() 
           .filter(b -> !CollectionUtils.isEmpty(b.getTeacherIds())) 
           .map(b -> b.getTeacherIds()) 
           .collect(Collectors.toSet()); 

समस्या, पोस्ट नक्शा ऑपरेशन है यह तार के सेट का संग्रह होता:

नीचे कोड लाइन है। तो ऑपरेशन संग्रह Set<Set<String>> देता है लेकिन मैं सभी मानों को एक सेट में एकत्रित करना चाहता हूं।

उत्तर

7

आप flatMap बजाय map उपयोग करने की आवश्यकता:

Set<String> teacherIds = 
    batches.stream() 
      .flatMap(b -> b.getTeacherIds().stream()) 
      .collect(Collectors.toSet()); 

ध्यान दें कि खाली संग्रह के लिए फ़िल्टरिंग अनावश्यक है - एक खाली संग्रह स्ट्रीमिंग के परिणामस्वरूप एक खाली स्ट्रीम होगी, जो अंतिम परिणाम को प्रभावित नहीं करेगा। यदि getTeacherIds()null लौटा सकता है, हालांकि, आपको अभी भी इसे संभालना होगा। filter(Objects::nonNull) का उपयोग करना पर्याप्त होगा, और आपको अपाचे कॉमन्स पर निर्भरता बचाएगा।

+1

क्या होगा यदि b.getTeacherIds एक शून्य है? –

+1

@ बिस्किटकोडर तर्क, अच्छा बिंदु - धाराएं नल को अच्छी तरह से संभालती नहीं हैं। मैं इसे संपादित करूंगा। – Mureinik

+1

@Mureinik 'फ़िल्टर (ऑब्जेक्ट्स :: nonNull) 'पर्याप्त नहीं होगा। आप 'stream' को 'flatMap' के अंदर एक शून्य संदर्भ पर कॉल करेंगे ... – Eugene

2

आप flatMap का उपयोग सभी मानों का एक फ्लैट Stream प्राप्त करने के लिए कर सकते हैं, और फिर एक Set<String> को एकत्रित करते हैं:

Set<String> teacherId = 
    batches.stream() 
      .filter(b -> !CollectionUtils.isEmpty(b.getTeacherIds())) 
      .flatMap(b -> b.getTeacherIds().stream()) 
      .collect(Collectors.toSet()); 
+2

मैं इस संदिग्ध उपयोगिता विधि से छुटकारा पाने का अवसर उपयोग करूंगा। यदि संभावित 'शून्य' से निपटना वांछित है, तो इसे स्पष्ट किया जाना चाहिए, '.filter (b -> b.getTeacherIds()! = Null)', खाली सूचियां पहले से ही 'flatMap' द्वारा नियंत्रित की जाती हैं। – Holger

+0

@ होल्गर मैंने पहले स्थान पर कलेक्शन यूटिलसिस इफेक्टि पेश किया है। लेकिन मुझे समझ में आता है कि खाली चेक डालने के लिए अप्रासंगिक है और केवल शून्य जांच पर्याप्त होगी। –

2

यदि आप परवाह है कि getTeacherIds() शून्य नहीं है, तो इसे != के माध्यम से स्पष्ट रूप से उपयोग करें, CollectionUtils.isEmpty बस सामान छुपाता है। खासकर जब से getTeacherIds() एक खाली संग्रह देता है - जिसे flatMap द्वारा ठीक से संभाला जाता है, इसलिए मुझे इसकी आवश्यकता नहीं है।

Set<String> teacherIds = batches 
      .stream() 
      .filter(x -> x.getTeacherIds() != null) 
      .flatMap(x -> x.getTeacherIds().stream()) 
      .collect(Collectors.toSet()); 
1

मैं अगर यह लैम्ब्डा अभिव्यक्ति का उपयोग करते संभव है सोच रहा हूँ।

मैं आखिरी मछली को पकड़ता हूं, :)।

Set<String> teacherIds = batches.stream()//v--- the class of `x` 
           .map(XClass::getTeacherIds) 
           .filter(Objects::nonNull) 
           .flatMap(Collection::stream) 
           .collect(Collectors.toSet()); 

नोट: मैं माफी चाहता मैं आपको बताना भूल कर रहा हूँ अगर getTeacherIds आईडी का एक नया सेट करने के लिए आंतरिक आईडी कॉपी कर रहा हूँ, कोड ऊपर आपके लिए उपयुक्त है। चूंकि इसे एक बार XClass से आईडी पढ़ी जाती है।

+0

getTeacherIds को ध्यान में रखकर शून्य वापस आ सकता है, क्या नक्शा एनपीई को संभालता है? –

+0

तो मैप फ़ंक्शन प्रत्येक तत्व पर पुनरावृत्त करता है, जो प्राप्त करता है उसे प्राप्त करता है टीचर आईडी प्रत्येक तत्व के लिए लौटाता है और getTeacherIds परिणामों की एक स्ट्रीम बनाता है। वहां से सीधा है।क्या मुझे यह सही समझ रहा है ? –

+0

@ बिस्किटकोडर हाँ, आप सही हैं। 'map' एनपीई फेंकता नहीं है, एनपीई' flatMap' में होता है। –

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