जावा हैशटैग पर एक से दूसरे की सामग्री को कैसे रखें, लेकिन मौजूदा कुंजियों और मूल्यों को प्रतिस्थापित न करें?


83

मुझे एक A HashMap से दूसरे एक B पर सभी कुंजियों और मानों को कॉपी करने की आवश्यकता है, लेकिन मौजूदा कुंजियों और मूल्यों को बदलने के लिए नहीं।

ऐसा करने का सबसे अच्छा तरीका क्या है?

मैं इसके बजाय keySet और checkig को पुनरावृत्त करने के बारे में सोच रहा था कि यह मौजूद है या नहीं, मैं करूँगा

Map temp = new HashMap(); // generic later
temp.putAll(Amap);
A.clear();
A.putAll(Bmap);
A.putAll(temp);

जवाबों:


108

ऐसा लगता है कि आप एक अस्थायी बनाने के लिए तैयार हैं Map, इसलिए मैं इसे इस तरह से करूंगा:

Map tmp = new HashMap(patch);
tmp.keySet().removeAll(target.keySet());
target.putAll(tmp);

यहाँ, patchवह मानचित्र है जिसे आप मानचित्र में जोड़ रहे हैं target

लुइस वासरमैन के लिए धन्यवाद , यहां एक संस्करण है जो जावा 8 में नए तरीकों का लाभ उठाता है:

patch.forEach(target::putIfAbsent);

इस मामले में आपको ऐसा करने की आवश्यकता नहीं है removeAllक्योंकि वे वैसे भी ओवरराइड हो जाएंगे।
रेकवेन्ड गोंजो

@ गोंजेंडो: ओवरराइट किसके द्वारा लिखा गया?
इक्विकसन

@luksmir नहीं, जो मौजूदा प्रविष्टियों को हटा देगा जिन्हें संरक्षित किया जाना चाहिए।
एरिकसन

नमस्ते! MapWithValues.putAll (mapWithAnotherValues) काम क्यों नहीं करते?
betomoretti

15
@erickson एक और अधिक कॉम्पैक्ट जावा 8 संस्करण patch.forEach(target::putIfAbsent):।
लुई वासरमैन 20

15

का उपयोग करते हुए अमरूद के नक्शे 2 नक्शे का अंतर आप एक पंक्ति में कर सकते हैं, एक विधि हस्ताक्षर जो इसे और अधिक स्पष्ट आप क्या हासिल करने की कोशिश कर रहे हैं बनाता है के साथ गणना करने के लिए वर्ग 'उपयोगिता तरीके:

public static void main(final String[] args) {
    // Create some maps
    final Map<Integer, String> map1 = new HashMap<Integer, String>();
    map1.put(1, "Hello");
    map1.put(2, "There");
    final Map<Integer, String> map2 = new HashMap<Integer, String>();
    map2.put(2, "There");
    map2.put(3, "is");
    map2.put(4, "a");
    map2.put(5, "bird");

    // Add everything in map1 not in map2 to map2
    map2.putAll(Maps.difference(map1, map2).entriesOnlyOnLeft());
}

8

बस पुनरावृति और जोड़ें:

for(Map.Entry e : a.entrySet())
  if(!b.containsKey(e.getKey())
    b.put(e.getKey(), e.getValue());

जोड़ने के लिए संपादित करें:

यदि आप एक में परिवर्तन कर सकते हैं, तो आप भी कर सकते हैं:

a.putAll(b)

और एक बिल्कुल वही होगा जो आपको चाहिए। (सभी प्रविष्टियाँ bऔर सभी प्रविष्टियाँ aउस में नहीं हैं b)


1.) entrySet()रिटर्न a Set<Map.Entry>। 2.) के लिए कोई विधि नहीं contains(...)है java.util.Map
फाबियान बार्नी

वहाँ एक चालाक रास्ता नहीं है? एक संग्रह उपयोगिता की तरह या तो? मुझे हर जगह छोरों से नफरत है।
रैपादुरा

1
@AntonioP: सभी जगह सभी छोरों के लिए? लूप के लिए एक है और यह लगभग सीधा है जैसा कि आप प्राप्त कर सकते हैं।
रेनॉन्ड गोंजो

+1 तब, बस काम करता है जब मैप्स कच्चे प्रकार के साथ उपयोग नहीं किए जाते हैं, मुझे लगता है। अपने आप को Map.Entry :-)
Fabian Barney

@ गोंजो, आह, कोड में कहीं और। :) अभिप्रेरित करें। मौजूदा कुंजियों और मानों को बदल दें? बीमार इस अर्थ के साथ जाओ यह सबसे सीधा तरीका लगता है।
रैपादुरा २५'११ को १24:

5

अगर आप @ erickson के सॉल्यूशन में मैप्स ऑर्डर बदलते हैं तो आप इसे सिर्फ 1 लाइन में बना सकते हैं:

mapWithNotSoImportantValues.putAll( mapWithImportantValues );

इस स्थिति में आप mapWithNotSoImportantValues ​​में मानों को उसी मान से MapWithImportantValues ​​के मान से प्रतिस्थापित करते हैं।


2
public class MyMap {

public static void main(String[] args) {

    Map<String, String> map1 = new HashMap<String, String>();
    map1.put("key1", "value1");
    map1.put("key2", "value2");
    map1.put("key3", "value3");
    map1.put(null, null);

    Map<String, String> map2 = new HashMap<String, String>();
    map2.put("key4", "value4");
    map2.put("key5", "value5");
    map2.put("key6", "value6");
    map2.put("key3", "replaced-value-of-key3-in-map2");
    // used only if map1 can be changes/updates with the same keys present in map2.
    map1.putAll(map2);

    // use below if you are not supposed to modify the map1.
    for (Map.Entry e : map2.entrySet())
        if (!map1.containsKey(e.getKey()))
            map1.put(e.getKey().toString(), e.getValue().toString());
    System.out.println(map1);
}}

2

जावा 8 के साथ आपकी आवश्यकता को पूरा करने के लिए यह एपीआई विधि है।

map.putIfAbsent(key, value)

यदि निर्दिष्ट कुंजी पहले से ही एक मूल्य से जुड़ी नहीं है (या नल करने के लिए मैप की गई है) तो उसे दिए गए मूल्य के साथ जोड़ देता है और शून्य देता है, अन्यथा वर्तमान मान लौटाता है।


1
क्या हम डाल सकते हैं। मुझे इसी की जरूरत थी ?
user1735921

0

जैसा कि दूसरों ने कहा है, आप उपयोग कर सकते हैं putIfAbsent। उस नक्शे में प्रत्येक प्रविष्टि के बारे में बताएं जिसे आप सम्मिलित करना चाहते हैं, और मूल नक्शे पर इस विधि को लागू करें:

mapToInsert.forEach(originalMap::putIfAbsent);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.