2014-10-28 19 views
6

मैं जावा में flatMapOptional एस की कोशिश कर रहा हूं।जावा 8 flatMap + Optional.of संकलित नहीं करता

List<String> x = Arrays.asList("a", "b", "c"); 
List<String> result = x.stream().flatMap((val) -> val.equals("b") ? Optional.empty() : Optional.of(val)).collect(Collectors.toList()); 

मैं संकलक से इस त्रुटि संदेश मिलता है:

Error:(10, 27) java: incompatible types: no instance(s) of type variable(s) T exist so that java.util.Optional<T> conforms to java.util.stream.Stream<? extends R> 

क्या गलत है यहाँ एक सरल उदाहरण है?

List("a", "b", "c").flatMap(x => if (x == "b") None else Some(x)) 

यह रिटर्न:

res2: List[String] = List(a, c) 

अपेक्षा के अनुरूप यहाँ मैं क्या स्काला में प्राप्त करने के लिए कोशिश कर रहा हूँ का एक उदाहरण है।

मैं इसे जावा में कैसे परिवर्तित करूं ताकि यह संकलित हो सके?

उत्तर

2

कोई सौदा करने की जरूरत है यहां Optional के साथ।

सरल सीधी-सपाट समाधान flatMap के प्रयोग पर filter

List<String> result = x.stream() 
    .filter(val -> !val.equals("b")) 
    .collect(Collectors.toList()); 

यदि आप जोर देते हैं उपयोग करने के लिए है, तो आप बस Stream बजाय Optional का उपयोग करना चाहिए:

List<String> result = x.stream().flatMap(
    val -> val.equals("b")? Stream.empty(): Stream.of(val)) 
    .collect(Collectors.toList()); 

आप से निपटने के लिए है, तो एक ऑपरेशन जो अनजाने में Optional उत्पन्न करता है, आपको Stream.flatMap:

0 का उपयोग करने के लिए इसे Stream में परिवर्तित करना होगा।
List<String> result = x.stream() 
    .map(val -> val.equals("b") ? Optional.<String>empty() : Optional.of(val)) 
    .flatMap(o->o.map(Stream::of).orElse(Stream.empty())) 
    .collect(Collectors.toList()); 
6

flatMap इनपुट Stream इनपुट के तत्व को एक अलग Stream में मैप करने की उम्मीद है। इसलिए इसे Stream वापस करना होगा और Optional नहीं होगा।

इसलिए, आप कुछ इस तरह करना चाहिए:

List<String> x = Arrays.asList("a", "b", "c"); 
List<Optional<String>> result = 
    x.stream() 
    .flatMap((val) -> 
        val.equals("b") ? Stream.of(Optional.empty()) : 
            Stream.of(Optional.of(val))) 
    .collect(Collectors.toList()); 

ध्यान दें कि यदि आपका लक्ष्य बस है मूल्यों के कुछ की ("बी" अपने उदाहरण में) छुटकारा पाने के लिए, आप की जरूरत नहीं है बिल्कुल वैकल्पिक का उपयोग करें। तुम बस स्ट्रीम फ़िल्टर कर सकते हैं:

List<String> result = 
    x.stream() 
    .filter (val -> !val.equals("b")) 
    .collect(Collectors.toList()); 

इस तरह आप flatMap की जरूरत नहीं है और अपने उत्पादन एक List<String> बजाय एक List<Optional<String>> है।

रूप होल्गर टिप्पणी की, समाधान है कि रिटर्न Optional रों की एक StreamflatMap के बजाय map का उपयोग करके सरल किया जा सकता है, क्योंकि प्रत्येक तत्व में एक अकेला Optional में मैप किया गया है:

List<String> x = Arrays.asList("a", "b", "c"); 
List<Optional<String>> result = 
    x.stream() 
    .map((val) -> val.equals("b") ? Optional.empty() : Optional.of(val)) 
    .collect(Collectors.toList()); 
+0

धन्यवाद! आम तौर पर मैं फ़िल्टर करता हूँ। इस मामले में (वास्तविक मामला, सरलीकृत खिलौना उदाहरण नहीं) मैं वैकल्पिक विकल्प का उपयोग करना चाहता हूं क्योंकि फ़िल्टरिंग का मतलब बहुत सारे बकवास के माध्यम से खोदना होगा जो मुझे मानचित्र-चरण में भी करना होगा। – auramo

+1

जब स्ट्रीम के प्रत्येक तत्व को एक 'वैकल्पिक' पर मैप किया जाता है, तो 'flatMap' का उपयोग करने की कोई आवश्यकता नहीं होती है। बस '.map (val -> val.equals ("b") का उपयोग करें? वैकल्पिक .empty(): वैकल्पिक।(वैल)) ' – Holger

+0

@ होल्गर आप बिल्कुल सही हैं। मैंने इसके बारे में नहीं सोचा था। मैं एक फ्लैटमैप का उपयोग करने के ओपी के फैसले का पालन कर रहा था। – Eran

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