2014-04-26 7 views
7

इस प्रश्न में जावा 8 कलेक्टरों का उपयोग करके तत्वों का मानचित्रण और समूह बनाना शामिल है। मुझे रोगी की एक सूची मिली है। प्रत्येक रोगी के पास उन विभागों की एक सूची है जहां उन्होंने दौरा किया था। कहें कि मैं प्रत्येक विभाग के लिए गिनना चाहता हूं कि जावा 8 में नए कलेक्टर एपीआई का उपयोग करके कितनी बार देखा गया था, मैं विभाग सूची से कैसे समूह करूंगा?जावा 8 संग्राहक API

धन्यवाद!

नोट: मुझे पता है कि मैं प्रत्येक विभाग में एक काउंटर डाल सकता हूं, यह प्रश्न पूरी तरह से नई जावा 8 सुविधाओं को सीखने के उद्देश्य से है।

कोड:

public class Patient { 
    private String id; 
    private List<Department> history; 
    /* some more getters/setters come here */ 
} 

अपने मुख्य विधि में मैं रोगी की एक सूची है। मैं विभाग विभाग (या विस्तार या सजावट) को संपादित किए बिना, प्रत्येक विभाग के लिए जानना चाहता हूं कि कितनी बार इसका दौरा किया गया था।

मुझे लगता है कि मुझे रोगियों की एक धारा लेनी है और उन्हें डिप्टी-> गिनती के मानचित्र पर मैप करना है (कितनी बार प्रत्येक मरीज का दौरा किया जाता है।)। इन मानचित्रों की एक धारा होने के बाद - मुझे नहीं पता कि इन मानचित्रों को समूहित करने और उन्हें गिनने के लिए क्या करना है।

+0

यह शायद सबसे अच्छा समझाया गया है कोड द्वारा कृपया अपने रोगी और विभाग कोड को परिभाषित करें ताकि सभी उस पर हुक कर सकें। –

+0

@owlstead: मैंने कक्षा रोगी के खेतों को जोड़ा। यह आसान होना चाहिए मैं बस यह नहीं कर सकता कि इसे कैसे किया जाए। ध्यान दें कि मैंने विभाग के लिए कोड नहीं जोड़ा है क्योंकि इसका कोई महत्व नहीं है, यह आसानी से एक स्ट्रिंग –

उत्तर

11

सबसे पहले, मुझे लगता है कि यदि एक रोगी एक से अधिक विभागों का दौरा करता है, तो वह विभाग रोगी की इतिहास सूची में एक से अधिक बार दिखाई देगा।

अगर ऐसी बात है, तो हम बस मरीजों के बारे में हमारी स्ट्रीम और flatMap यह विभाग है, जहां एक विभाग की घटना एक रोगी से एक यात्रा इंगित करता है की एक धारा को ले जा सकते हैं।

फिर हम इसे groupingBy कलेक्टर में पास कर सकते हैं। हम स्वयं विभाग द्वारा वर्गीकृत करना चाहते हैं, इसलिए क्लासिफायर फ़ंक्शन पहचान कार्य है।

मूल्य के लिए, यदि हम विभाग के लिए कोई प्रविष्टि अभी तक मौजूद नहीं हैं, तो हम मूल्य के रूप में 1 रखना चाहते हैं, लेकिन यदि कोई प्रविष्टि मौजूद है तो हम मौजूदा मान में 1 जोड़ना चाहते हैं। counting() नामक एक कलेक्टर है जो हमारे लिए पहले से ही ऐसा करता है, इसलिए हम इसे डाउनस्ट्रीम कलेक्टर के रूप में groupingBy() पर पास करते हैं।

import static java.util.stream.Collectors.*; 

List<Patient> patients = ... ; 

Map<Department, Long> frequency = 
    patients.stream() 
     .flatMap(p -> p.getHistory().stream()) 
     .collect(groupingBy(d -> d, counting())); 

नोट है कि अगर एक विभाग का दौरा किया नहीं किया गया है, यह बस नक्शे से अनुपस्थित हो जाएगा:

जिसके परिणामस्वरूप कोड इस प्रकार है। आप विभागों की एक सूची है, तो आप इस तरह शून्य मान भर कर सकते हैं:

departments.forEach(d -> frequency.putIfAbsent(d, 0L)); 

या यदि आप, get तरफ शून्य को भरने के लिए चाहते हैं

long numVisits = frequency.getOrDefault(dept, 0L); 
+0

आसानी से दिखता है, और काम करता प्रतीत होता है। आपको ध्यान रखना चाहिए कि आपने स्थिर रूप से कलेक्टरों को आयात किया है। क्या आप समाधान के तर्क की व्याख्या कर सकते हैं? –

+1

@nocgod मुझे लगता है कि मैं उसी समय स्पष्टीकरण में टाइप कर रहा था जब आप इसके लिए पूछ रहे थे।:-) –

+1

मुझे लगता है कि आप थे :) मुझे इस पूरे कार्यात्मक लैम्ब्डा शैली में जाने के लिए थोड़ा स्विच करना होगा - मेरे पीपीएल पाठ्यक्रम और योजना भाषा के बाद से इसे छूना नहीं था। एक बार फिर धन्यवाद! –