2015-06-20 10 views
6

के साथ अटक गया है Doctor की कक्षा को बचाने के लिए मेरे पास Map<Integer,Doctor> docLib=new HashMap<>(); है।java8 lambda अभिव्यक्ति

Class Doctormethods:getSpecialization() वापसी एक String,
getPatients() वर्ग Person का संग्रह वापस जाने के लिए है।

मुख्य विधि में, मैं टाइप करें:

public Map<String,Set<Person>> getPatientsPerSpecialization(){ 
    Map<String,Set<Person>> res=this.docLib.entrySet().stream(). 
         map(d->d.getValue()). 
         collect(groupingBy(d->d.getSpecialization(), 
              d.getPatients()) //error 
           ); 
    return res; 
} 

आप देख सकते हैं, मैं groupingBy के साथ समस्या यह है, मैं विधि को एक जैसा मान घ भेजने का प्रयास करें, लेकिन यह गलत है। इसे कैसे हल करें?

+0

ऐसा लगता है कि आपको इस प्रश्न के कुछ अच्छे जवाब मिल गए हैं, लेकिन भविष्य में, कृपया आपको प्राप्त होने वाले सटीक त्रुटि संदेश और आपके अपेक्षित व्यवहार से अलग किसी भी अन्य व्यवहार के विवरण शामिल करें। "यह गलत है" कह रहा है आपकी समस्या के बारे में ज्यादा कुछ नहीं कहता है। – skrrgwasme

उत्तर

5

आपको लगता है कि mapping के लिए एक दूसरे कलेक्टर की जरूरत है:

public Map<String,Set<Person>> getPatientsPerSpecialization(){ 
    return this.docLib 
       .values() 
       .stream() 
       .collect(Colectors.groupingBy(Doctor::getSpecialization, 
              Collectors.mapping(Doctor::getPatients,toSet())) 
         ); 
} 

संपादित करें:

मुझे लगता है कि मेरी मूल जवाब गलत हो सकता है (यह परीक्षण करने में सक्षम होने के बिना कहना मुश्किल है)। चूंकि Doctor::getPatients संग्रह देता है, मुझे लगता है कि मेरा कोड वांछित Map<String,Set<Person>> के बजाय Map<String,Set<Collection<Person>>> वापस कर सकता है।

कि काबू पाने के लिए सबसे आसान तरीका से अधिक पुनरावृति करने के लिए कि Map फिर से निर्माण करने के लिए है वांछित Map:

public Map<String,Set<Person>> getPatientsPerSpecialization(){ 
    return this.docLib 
       .values() 
       .stream() 
       .collect(Colectors.groupingBy(Doctor::getSpecialization, 
              Collectors.mapping(Doctor::getPatients,toSet())) 
         ) 
       .entrySet() 
       .stream() 
       .collect (Collectors.toMap (e -> e.getKey(), 
              e -> e.getValue().stream().flatMap(c -> c.stream()).collect(Collectors.toSet())) 
         ); 
} 

शायद वहाँ एक रास्ता एक भी स्ट्रीम पाइप लाइन के साथ एक ही परिणाम प्राप्त करने के है, लेकिन मैं नहीं कर सकता इसे अभी देखें।

+2

'docLib.entrySet() स्ट्रीम()। मानचित्र (डी-> d.getValue()) के बजाय 'आप' docLib.values ​​()। स्ट्रीम()' लिख सकते हैं। – Jesper

+1

@ जेस्पर यह एक अच्छा मुद्दा है। मैंने उसे नहीं देखा। धन्यवाद। – Eran

+0

[जावा 9 के लिए प्रतीक्षा करें; -)] (http://download.java.net/jdk9/docs/api/java/util/stream/Collectors.html#flatMapping-java.util.function.Function-java.util .stream.Collector-) – Holger

2

के बजाय groupingBy, आप toMap इस्तेमाल कर सकते हैं:

public Map<String, Set<Person>> getPatientsPerSpecialization() { 
    return docLib.values() 
       .stream() 
       .collect(toMap(Doctor::getSpecialization, 
           d -> new HashSet<>(d.getPatients()), 
           (p1, p2) -> Stream.concat(p1.stream(), p2.stream()).collect(toSet()))); 
} 

क्या यह होता है कि यह समूह विशेषज्ञता प्रति डॉक्टरों और मरीजों यह है (ताकि एक Map<String, Set<Person>>) का एक सेट करने के लिए हर एक नक्शा है।

यदि पाइपलाइन से डेटा एकत्र करते समय, आपको एक विशेषज्ञ के साथ एक डॉक्टर का सामना करना पड़ता है जो पहले से ही मानचित्र में एक कुंजी के रूप में संग्रहीत है, तो आप दोनों सेटों के साथ मूल्यों का एक नया सेट तैयार करने के लिए मर्ज फ़ंक्शन का उपयोग करते हैं (सेट जो कुंजी के लिए पहले से ही एक मान के रूप में संग्रहीत है, और वह सेट जिसे आप कुंजी से जोड़ना चाहते हैं)।

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