2016-10-13 3 views
5

मेरे पास जावा लैम्ब्डा स्ट्रीम है जो एक फ़ाइल को पार करती है और परिणाम को कुछ बुनियादी फ़िल्टरिंग के आधार पर संग्रह में संग्रहीत करती है।विभिन्न संग्रहों में जावा लैम्ब्डा स्ट्रीम

मैं सिर्फ लैम्बडा सीख रहा हूं इसलिए अगर यह हास्यास्पद रूप से खराब है तो मेरे साथ यहां भालू। लेकिन कृपया मेरी गलतियों को इंगित करने के लिए स्वतंत्र महसूस करें।

किसी दिए गए फ़ाइल के लिए:

#ignored 
this 
is 
#ignored 
working 
fine 

कोड:

List<String> matches; 

Stream<String> g = Files.lines(Paths.get(givenFile)); 

matches = g.filter(line -> !line.startsWith("#")) 
      .collect(Collectors.toList()); 

["this", "is", "working", "fine"] 

अब, मैं इस एक ही स्ट्रीम के भीतर एक दूसरी सूची में नजरअंदाज कर दिया लाइनों का संग्रह के बारे में जाना होगा? कुछ की तरह:

List<String> matches; 
List<String> ignored; // to store lines that start with # 

Stream<String> g = Files.lines(Paths.get(exclusionFile.toURI())); 

matches = g.filter(line -> !line.startsWith("#")) 
      // how can I add a condition to throw these 
      // non-matching lines into the ignored collection? 
      .collect(Collectors.toList()); 

मुझे लगता है यह बहुत एक नई धारा को खोलने के लिए तुच्छ हो सकता है, तर्क थोड़ा, और .collect() आसानी से पर्याप्त ध्यान नहीं दिया लाइनों को बदलने। लेकिन अगर मैं इसे एक स्ट्रीम में कर सकता हूं तो मैं इस फाइल को दो बार लूप नहीं करना चाहता हूं।

+0

यह 'g.filter (..) जैसे कुछ होना चाहिए। नक्शा (टी-> टी :: toString))। संग्रह (.. toList())' –

+0

ओरेकल दस्तावेज़ों में अंतिम उदाहरण देखें: https: //docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html – Gene

उत्तर

13
दो धाराओं के बजाय

आप कलेक्टर में partitioningBy उपयोग कर सकते हैं

List<String> strings = Arrays.asList("#ignored", "this", "is", "#ignored", "working", "fine"); 
Map<Boolean, List<String>> map = strings.stream().collect(Collectors.partitioningBy(s -> s.startsWith("#"))); 
System.out.println(map); 

उत्पादन

{false=[this, is, working, fine], true=[#ignored, #ignored]} 

यहाँ मैं Boolean के रूप में प्रमुख थे, लेकिन आप एक सार्थक स्ट्रिंग या enum

को बदल सकते हैं संपादित करें

कर सकते हैं तार कुछ अन्य विशेष वर्ण के साथ शुरू होता है तो आप इस्तेमाल कर सकते हैं groupingBy

List<String> strings = Arrays.asList("#ignored", "this", "is", "#ignored", "working", "fine", "!Someother", "*star"); 
    Function<String, String> classifier = s -> { 
     if (s.matches("^[[email protected]#$%^&*]{1}.*")) { 
      return Character.toString(s.charAt(0)); 
     } else { 
      return "others"; 
     } 
    }; 
    Map<String, List<String>> maps = strings.stream().collect(Collectors.groupingBy(classifier)); 
    System.out.println(maps); 

आउटपुट

{!=[!Someother], #=[#ignored, #ignored], *=[*star], others=[this, is, working, fine]} 

भी आप घोंसला groupingBy और partitioningBy

+1

यह शानदार ढंग से काम किया, धन्यवाद। – AWT

1

मैं निकटतम आप के लिए आ सकता है सोच सकते हैं इसके लिए एक सामान्य दृष्टिकोण peek:

जैसा कुछ होगा

मैं इसका उल्लेख करता हूं क्योंकि विभाजन Collector विभाजन के विपरीत, कम से कम सिद्धांत में, आप एक साथ बदल सकते हैं, हालांकि peek एस आप चाहते हैं - लेकिन, जैसा कि आप देख सकते हैं, आपको तर्क को डुप्लिकेट करना होगा, इसलिए यह आदर्श नहीं है।

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