2015-09-11 16 views
12

मैं इसस्ट्रीम :: flatMap का यह उपयोग गलत क्यों है?

public static List<String> duplicate(String s) { 

    List<String> l = new ArrayList<String>(); 
    l.add(s); 
    l.add(s); 

    return l; 
} 


listOfStrings.stream().flatMap(str -> duplicate(str)).collect(Collectors.toList()); 

तरह स्ट्रीम :: flatMap उपयोग करने में सक्षम होने की उम्मीद लेकिन मैं निम्नलिखित संकलक त्रुटि

Test.java:25: error: incompatible types: cannot infer type-variable(s) R listOfStrings.stream().flatMap(str -> duplicate(str)).collect(Collectors.toList());

(argument mismatch; bad return type in lambda expression List cannot be converted to Stream)
where R,T are type-variables: R extends Object declared in method flatMap(Function>) T extends Object declared in interface Stream

स्केला में मैं क्या कर सकते हैं मैं बराबर होने का विश्वास है कि मिल

scala> List(1,2,3).flatMap(duplicate(_)) 
res0: List[Int] = List(1, 1, 2, 2, 3, 3) 

जावा में फ्लैटमैप का वैध उपयोग क्यों नहीं है?

उत्तर

19

flatMap में लैम्ब्डा अभिव्यक्ति के रूप में flatMap का तर्क प्रकार Function<? super T, ? extends Stream<? extends R>> की है जिसके द्वारा देखा जा सकता है, एक Stream वापस जाने के लिए की जरूरत है।

निम्नलिखित कोड संकलन और ठीक चलेगा:

listOfStrings.stream() 
      .flatMap(str -> duplicate(str).stream()) // note the .stream() here 
      .collect(Collectors.toList()); 

क्योंकि लैम्ब्डा अभिव्यक्ति str -> duplicate(str).stream() प्रकार Function<String, Stream<String>> की है।

6

यदि आप स्ट्रीम में प्रत्येक ऑब्जेक्ट को कई बार डुप्लिकेट करना चाहते हैं, तो आपको अतिरिक्त ArrayList के साथ इस पर मेमोरी बर्बाद करने की आवश्यकता नहीं है। कई छोटे और तेज विकल्प हैं।

  • Stream.generate का उपयोग कर नई धारा उत्पन्न करें, फिर इसे सीमित:

    listOfStrings.stream() 
          .flatMap(str -> Stream.generate(() -> str).limit(2)) 
          .collect(Collectors.toList()); 
    
  • IntStream.range के माध्यम से संख्या के अनुक्रम उत्पन्न और उन्हें एक ही स्ट्रिंग के लिए नक्शे:

    listOfStrings.stream() 
          .flatMap(str -> IntStream.range(0, 2).mapToObj(i -> str)) 
          .collect(Collectors.toList()); 
    
  • उपयोग अच्छे पुराने Collections.nCopies:

    listOfStrings.stream() 
          .flatMap(str -> Stream.of(str, str)) 
          .collect(Collectors.toList()); 
    
    :
    listOfStrings.stream() 
          .flatMap(str -> Collections.nCopies(2, str).stream()) 
          .collect(Collectors.toList()); 
    

आप यह सुनिश्चित करें कि आप हमेशा ठीक दो बार नकल कर रहे हैं तो इस बात कम से कम विकल्प है

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