मर्ज फ़ंक्शन में कुंजी प्राप्त करने का कोई मौका नहीं है, जो एक ही समस्या है, बिल्टिन फ़ंक्शन में, जब आप मर्ज फ़ंक्शन को छोड़ देते हैं।
public static <T, K, V> Collector<T, ?, Map<K,V>>
toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends V> valueMapper) {
return Collector.of(HashMap::new,
(m, t) -> {
K k = keyMapper.apply(t);
V v = Objects.requireNonNull(valueMapper.apply(t));
if(m.putIfAbsent(k, v) != null) throw duplicateKey(k, m.get(k), v);
},
(m1, m2) -> {
m2.forEach((k,v) -> {
if(m1.putIfAbsent(k, v)!=null) throw duplicateKey(k, m1.get(k), v);
});
return m1;
});
}
private static IllegalStateException duplicateKey(Object k, Object v1, Object v2) {
return new IllegalStateException("Duplicate key "+k+" (values "+v1+" and "+v2+')');
}
(यह मूलतः है क्या किसी मर्ज समारोह के बिना toMap
के जावा 9 के कार्यान्वयन करना होगा)
:
समाधान एक अलग toMap
कार्यान्वयन, जो Map.merge
पर निर्भर नहीं करता उपयोग करने के लिए है
तो आपको अपने कोड में करने की ज़रूरत है, toMap
कॉल को रीडायरेक्ट करना है और मर्ज फ़ंक्शन को छोड़ना है:
String keyvalp = "test=one\ntest2=two\ntest2=three";
Map<String, String> map = Pattern.compile("\n")
.splitAsStream(keyvalp)
.map(entry -> entry.split("="))
.collect(toMap(split -> split[0], split -> split[1]));
(या ContainingClass.toMap
अगर इसकी न तो एक ही कक्षा और न ही स्थिर आयात में) < \ sup>
कलेक्टर, मूल toMap
कलेक्टर की तरह समानांतर प्रसंस्करण का समर्थन करता है, हालांकि यह बहुत यहाँ समानांतर प्रसंस्करण से एक लाभ प्राप्त होने की संभावना नहीं है , प्रक्रिया के लिए और भी तत्वों के साथ।
हैं, अगर मैं आप सही तरीके से मिलता है, आप केवल या तो, पुराने या नए मूल्य लेने के लिए, मर्ज वास्तविक कुंजी के आधार पर समारोह में चाहते हैं, तो आप इसे एक महत्वपूर्ण Predicate
इस
public static <T, K, V> Collector<T, ?, Map<K,V>>
toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends V> valueMapper,
Predicate<? super K> useOlder) {
return Collector.of(HashMap::new,
(m, t) -> {
K k = keyMapper.apply(t);
m.merge(k, valueMapper.apply(t), (a,b) -> useOlder.test(k)? a: b);
},
(m1, m2) -> {
m2.forEach((k,v) -> m1.merge(k, v, (a,b) -> useOlder.test(k)? a: b));
return m1;
});
}
तरह के साथ कर सकता
Map<String, String> map = Pattern.compile("\n")
.splitAsStream(keyvalp)
.map(entry -> entry.split("="))
.collect(toMap(split -> split[0], split -> split[1], key -> condition));
इस कलेक्टर अनुकूलित करने के लिए कई तरीके हैं ...
बाद में आप मर्ज किए गए मान फ़िल्टर कर सकते हैं, क्या वास्तव में उन्हें विलय करते समय फ़िल्टर करने की आवश्यकता है? –
क्या आप एक उदाहरण दे सकते हैं? विलय के दौरान मुझे यह तय करना होगा कि कौन से मूल्य लेना है (ओ 1 या ओ 2)। निर्णय ** कुंजी ** पर किया जाना चाहिए। लेकिन कुंजी हमेशा दो बार नहीं होती है।केवल कभी-कभी जिस मामले में विलय का निर्णय लिया जाना चाहिए। – membersound
ठीक है मैं देखता हूँ। आप अलग नक्शा बना सकते हैं और '.map (एंट्री -> entry.split (" = ")) चला सकते हैं। प्रत्येक()' के लिए और प्रत्येक प्रविष्टि की जांच करें यदि मान पहले से ही मानचित्र में है। यदि नहीं - जोड़ें, अन्य - जांचें कि क्या प्रतिस्थापित करें या नहीं। –