2017-05-21 8 views
9

मेरे पास MonitoredData नामक एक कक्षा है जिसके साथ एक गतिविधि, इसके प्रारंभिक समय और समाप्ति समय का वर्णन किया गया है। विशेषताएं activityLabel, startTime, endTime हैं। मुझे धाराओं का उपयोग करके इन गतिविधियों को समूहित और फ़िल्टर करना होगा, जिन गतिविधियों की कुल अवधि 10 घंटे से अधिक हो। मैं गतिविधि इस का उपयोग कर के अनुसार अवधियों का योग है और उन्हें समूह बनाने में कामयाब रहे:जावा स्ट्रीम फ़िल्टर मानों का योग

Map<String, Long> map4 = new HashMap<String, Long>(); 

map4 = data.stream() 
    .collect(
     Collectors.groupingBy(
      MonitoredData::getActivity, 
      Collectors.summingLong(MonitoredData::getDuration) 
     ) 
    ); //getDuration returns end Time - startTime in milliseconds 

लेकिन मैं एक फ़िल्टर जोड़ें करने में कामयाब नहीं किया है। मैंने इसका उपयोग करने की कोशिश की:

.filter(Collectors.summingLong(MonitoredData::getDuration) > whatever) 

लेकिन स्पष्ट रूप से यह काम नहीं करता है। इसे Map<String, Long> वापस करने के लिए मैं इसे कैसे हल कर सकता हूं?

+0

'संग्रह' ऑपरेशन से पहले '.filter' जोड़ें? –

+0

आपको पहले 'obj -> (obj, sumDuration)' मानचित्र करना चाहिए और फिर परिणामस्वरूप ऑब्जेक्ट पर फ़िल्टर लागू करना चाहिए। – NiVeR

+0

मैं फोन पर हूं, शायद आपका प्रश्न इस तरह से है [http] // http: // stackoverflow।com/प्रश्न/44097658/कैसे करने वाली भेजने-पैरामीटर-टु-ए-संदर्भ-विधि में एक धारा-जावा-8/44098230 # 44098230)/[कि] (http://stackoverflow.com/questions/44086903/कैसे-टू-एड-डेटाटाइम-वैल्यू-इन-ए-स्ट्रीमजवा/44087302 # 44087302) फ़िल्टरिंग को छोड़ देता है। आप ग्रौइंग/विलय करके और फिर फ़िल्टर करके अपना पूरा कर सकते हैं। –

उत्तर

3

मुझे लगता है कि यह है कि तुम क्या चाहते थे है, आप स्पष्ट रूप से इस तरह के नक्शे फिल्टर करने के लिए अपनी खुद की विधि लिख सकते हैं Google Guava Maps class:

Map<String, Long> map = Maps.filterValues(data.stream() 
      .collect(Collectors.groupingBy 
        (MonitoredData::getActivity, Collectors.summingLong 
          (MonitoredData::getDuration) 
        )), value -> value > 3); 

का उपयोग कर, लेकिन यह पहले से ही वहाँ के बाद से इतना लोकप्रिय पुस्तकालय पर ... शुद्ध धाराओं के साथ इसे कैसे करें: मुझे नहीं पता, लेकिन शायद यह संतोषजनक होगा।

+1

बहुत साफ! पूरी तरह से भूल गए कि आप अमरूद के साथ ऐसा कर सकते हैं। – Eugene

2

नीचे कोड जोड़े जाने के बाद नक्शा मिला:

map4.entrySet().stream() 
       .filter(a -> a.getValue() > whatever) 
       .collect(Collectors.joining()); 
4

यह कैसे के बारे में? मैं फोन पर जवाब देता हूं, आपको अपने आप से परीक्षण की आवश्यकता है।

map = map.entrySet() 
     .stream() 
     .filter(it->TimeUnit.MILLISECONDS.toHours(it.getValue())>10) 
     .collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue)); 

याCollectors#collectingAndThen का उपयोग कर:

map4 = data.stream() 
.collect(Collectors.collectingAndThen( 
    Collectors.groupingBy(
     MonitoredData::getActivity, 
     Collectors.summingLong(MonitoredData::getDuration) 
    ), 
    r1 -> r1.entrySet().stream() 
      .filter(it->TimeUnit.MILLISECONDS.toHours(it.getValue())>10) 
      .collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue)) 
)); 
6

मैं पहली बार के रूप में आप पहले से ही किया है क्या करना होगा: मैं, एक नक्शा करने के लिए MonitoredData उदाहरणों में से धारा इकट्ठा होता गतिविधि के द्वारा समूहीकरण और संक्षेप प्रत्येक मान में प्रत्येक गतिविधि की अवधि:

Map<String, Long> map4 = data.stream() 
    .collect(Collectors.groupingBy(
     MonitoredData::getActivity, 
     HashMap::new, 
     Collectors.summingLong(MonitoredData::getDuration))); 

अति सूक्ष्म अंतर है कि मैंउपयोग कर रहा हूँ है, क्योंकि अगले चरण में मैं उन प्रविष्टियों को हटाना चाहता हूं जिनकी अवधि 10 घंटों से कम है, और spec गारंटी नहीं देता है कि नक्शा Collectors.groupingBy विधियों द्वारा लौटाया गया है जो एक या दो तर्क लेते हैं।

यह कैसे मैं प्रविष्टियों है कि मेल नहीं हटाने होता है:

public static final long TEN_HOURS_MS = 10 * 60 * 60 * 1000; 

map4.values().removeIf(v -> v < TEN_HOURS_MS); 

आप एक पंक्ति में सब कुछ करना चाहते हैं, आप Collectors.collectingAndThen उपयोग करने के लिए चाहते हो सकता है:

Map<String, Long> map4 = data.stream() 
    .collect(Collectors.collectingAndThen(
     Collectors.groupingBy(
      MonitoredData::getActivity, 
      HashMap::new, 
      Collectors.summingLong(MonitoredData::getDuration)), 
     m -> { m.values().removeIf(v -> v < TEN_HOURS_MS); return m; })); 

यहां मैंने द्वारा दिए गए मानचित्र को संशोधित करने के लिए Collectors.collectingAndThen का उपयोग किया है। और, फिनिशर फ़ंक्शन के भीतर, मैंने Collection.removeIf का उपयोग किया है, जो भविष्यवाणी करता है और भविष्यवाणी करने वाली सभी प्रविष्टियों को हटा देता है।

+2

अच्छी नौकरी। अनिवार्य रूप से, मैं कल रात 'हटाओ' के बारे में सोचता हूं लेकिन मुझे यकीन नहीं है, मैं फोन पर हूं और मैं परीक्षण नहीं कर सकता। और आपके तरीके यह वर्णन करने के लिए अधिक स्पष्ट रूप से वर्णन करते हैं कि मानचित्र से 10 से कम अवधि किस अवधि से हटा दी गई है। –

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