2016-03-23 11 views
8

मैं String है और HashMap का उपयोग करके कोड नीचे की तरह hashmap मूल्य के साथ बदलाव स्ट्रिंग:जावा 8 धारा

Map<String, String> map = new HashMap<>(); 
    map.put("ABC", "123"); 
    String test = "helloABC"; 
    map.forEach((key, value) -> { 
     test = test.replaceAll(key, value); 
    }); 

और मैं HashMap मूल्यों के साथ स्ट्रिंग को बदलने के लिए प्रयास करते हैं, लेकिन यह काम नहीं करता क्योंकि test अंतिम है और forEach के शरीर में पुन: असाइन नहीं किया जा सकता है।

तो क्या String को HashMap के साथ जावा 8 स्ट्रीम एपीआई का उपयोग करने के लिए कोई समाधान है?

+2

'foreach()' सिंक्रनाइज़ नहीं कर रहा है। आपका कोड संकलित नहीं होता है क्योंकि आप अपने लैम्ब्डा अभिव्यक्ति के अंदर से 'संदेश' पर दुष्प्रभाव नहीं डाल सकते हैं। यहां तक ​​कि यदि आप कर सकते हैं, तो आपको मानचित्र में अंतिम मानचित्र प्रविष्टि के लिए 'test' पर अंतिम प्रतिस्थापन' संदेश मिलेगा। जो संभवतः आप नहीं चाहते हैं। इसके अलावा "आखिरी नक्शा प्रविष्टि" 'हैश मैप' के लिए गैर-निर्धारक है। – Ralf

+0

ठीक है धन्यवाद, मुझे मिल गया। लेकिन परीक्षण की सभी सामग्री को पहले से ही बदलने के लिए मुझे क्या करना चाहिए? –

उत्तर

3

इस रूप में उपयोग नहीं कर किया जा सकता है केवल forEach() (message प्रभावी ढंग से अंतिम होना चाहिए), वैकल्पिक हल के लिए एक अंतिम कंटेनर बनाने के लिए हो सकता है (उदाहरण के लिए List) जो एक एकल String जाता है कि फिर से लिखा संग्रहीत करता है:

final List<String> msg = Arrays.asList("helloABC"); 
map.forEach((key, value) -> msg.set(0, msg.get(0).replace(key, value))); 
String test = msg.get(0); 

ध्यान दें कि मैंने replaceAll() से replace() बदल दिया है क्योंकि रेगेक्स के साथ पूर्व कार्य करता है, लेकिन आपके कोड द्वारा निर्णय लेने से आपको स्ट्रिंग द्वारा प्रतिस्थापन की आवश्यकता होती है (चिंता न करें, भ्रमित नाम के बावजूद यह सभी घटनाओं को प्रतिस्थापित करता है)।

कि वास्तव में आप एपीआई स्ट्रीम चाहते हैं, आप reduce() आपरेशन का उपयोग हो सकता है:

String test = map.entrySet() 
       .stream() 
       .reduce("helloABC", 
         (s, e) -> s.replace(e.getKey(), e.getValue()), 
         (s1, s2) -> null); 

लेकिन ध्यान में रखना, कि इस तरह की कमी केवल धारावाहिक में ठीक से काम करेंगे (नहीं समानांतर) धारा, combiner समारोह है जहां कभी नहीं कहा जाता है (इस प्रकार कोई भी हो सकता है)।

+0

मैंने पहले से ही कोशिश की है, लेकिन यह बहुत मुश्किल लग रहा है। और अगर हमारे पास मानचित्र में कई तत्व हैं? –

+0

@ चाइवावनिन '0' 'सूची' को संदर्भित करता है, न कि 'मानचित्र' के लिए। 'forEach()' आपके पास जितनी मैप प्रविष्टियां संसाधित करेगा। –

+0

क्षमा करें, मैंने इसे स्पष्ट रूप से नहीं देखा :)। लेकिन ऐसा लगता है कि यह तर्क नहीं है। मैं बस पूरी तरह से जावा 8 स्ट्रीम के साथ काम करना चाहता हूँ। वैसे भी धन्यवाद :) –

3

इस प्रकार की समस्या स्ट्रीम एपीआई के लिए उपयुक्त नहीं है। धाराओं का वर्तमान अवतार मुख्य रूप से उन कार्यों पर निर्देशित किया जाता है जिन्हें समानांतर बनाया जा सकता है। शायद इस प्रकार के ऑपरेशन के लिए समर्थन भविष्य में जोड़ा जाएगा (https://bugs.openjdk.java.net/browse/JDK-8133680 देखें)।

एक धाराओं आधारित दृष्टिकोण है कि आपको दिलचस्प लग सकते कार्यों के बजाय स्ट्रिंग पर कम करने के लिए है:

Function<String, String> combined = map.entrySet().stream() 
    .reduce(
     Function.identity(), 
     (f, e) -> s -> f.apply(s).replaceAll(e.getKey(), e.getValue()), 
     Function::andThen 
    ); 

String result = combined.apply(test); 
+3

लगता है कि जावा-9 में 'foldLeft' देखने का कोई मौका नहीं है। दुर्भाग्य से। –

+1

@TagirValeev मैंने कुछ महीने पहले कोर-लिब मेलिंग सूची पर आपके प्रयासों को देखा था। कोशिश करने के लिए शुक्रिया। – Misha

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