2016-09-16 37 views
6

से अधिकतम आवृत्ति के साथ ऑब्जेक्ट प्राप्त करें मेरे पास city और zip फ़ील्ड्स वाला ऑब्जेक्ट है, चलो इसे Record पर कॉल करें।जावा 8 स्ट्रीम

public class Record() { 
    private String zip; 
    private String city; 

    //getters and setters 
} 

अब, मैं निम्नलिखित कोड का उपयोग कर zip द्वारा इन वस्तुओं का संग्रह, और मैं उन्हें समूह है:

final Collection<Record> records; //populated collection of records 
final Map<String, List<Record>> recordsByZip = records.stream() 
    .collect(Collectors.groupingBy(Record::getZip)); 

तो, अब मैं एक नक्शा जहां कुंजी zip और है मान Record ऑब्जेक्ट्स की एक सूची है जो zip के साथ है।

जो मैं अब प्राप्त करना चाहता हूं वह प्रत्येक zip के लिए सबसे आम city है।

recordsByZip.forEach((zip, records) -> { 
    final String mostCommonCity = //get most common city for these records 
}); 

मैं सभी स्ट्रीम संचालन के साथ ऐसा करना चाहता हूं। उदाहरण के लिए, मैं ऐसा करने से प्रत्येक city के लिए आवृत्ति का एक नक्शा प्राप्त करने में सक्षम हूँ:

recordsByZip.forEach((zip, entries) -> { 
    final Map<String, Long> frequencyMap = entries.stream() 
     .map(GisSectorFileRecord::getCity) 
     .filter(StringUtils::isNotBlank) 
     .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); 
}); 

लेकिन मैं एक एकल लाइन धारा आपरेशन कि अभी सबसे लगातार city वापस आ जाएगी ऐसा करने में सक्षम होना चाहते हैं ।

क्या वहां कोई जावा 8 स्ट्रीम गुरु है जो इस पर कुछ जादू कर सकता है?

यदि आप इसके साथ खेलना चाहते हैं तो यहां एक ideone sandbox है।

final Map<String, String> mostFrequentCities = 
    records.stream() 
     .collect(Collectors.groupingBy(
      Record::getZip, 
      Collectors.collectingAndThen(
       Collectors.groupingBy(Record::getCity, Collectors.counting()), 
       map -> map.entrySet().stream().max(Map.Entry.comparingByValue()).get().getKey() 
      ) 
     )); 

उनके जिप द्वारा इस समूह प्रत्येक रिकॉर्ड, और अपने शहरों से, प्रत्येक जिप के लिए शहरों की संख्या की गणना:

उत्तर

6

आप निम्न हो सकता था। फिर, ज़िप द्वारा शहरों की संख्या का नक्शा पोस्ट-प्रोसेस किया गया है ताकि केवल शहर को अधिकतम गिनती मिल सके।

+1

'संग्रह और तब मुझे पता था कि मुझे कुछ याद आ रहा था, लेकिन मैं हमेशा इसके बजाय 'मैपिंग' के बारे में सोचता हूं। +1 –

+0

क्या यह जांचने का कोई तरीका है कि '.max()' द्वारा वापस 'वैकल्पिक' स्ट्रीम स्ट्रीम ऑपरेशन में '.get()' पर कॉल करने से पहले मौजूद है या नहीं? –

+1

@AndrewMairose हां, लेकिन '.get() 'यहां कॉल करने के लिए सुरक्षित है, नक्शा कभी खाली नहीं हो सकता है, इसमें जरूरी है कि कम से कम शहर को ज़िप द्वारा समूहीकृत किया जाए। – Tunaki

0

मुझे लगता है कि मल्टीसेट इस तरह के प्रश्न के लिए एक अच्छा विकल्प है। यहाँ से AbacusUtil

Stream.of(records).map(e -> e.getCity()).filter(N::notNullOrEmpty).toMultiset().maxOccurrences().get().getKey(); 

प्रकटीकरण कोड है: मैं AbacusUtil के डेवलपर हूं।

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