मैं दो HashMap वस्तुओं को एक ही प्रकार से कैसे जोड़ सकता हूं?


241

मेरे पास दो HashMapवस्तुएं हैं जैसे:

HashMap<String, Integer> map1 = new HashMap<String, Integer>();
HashMap<String, Integer> map2 = new HashMap<String, Integer>();

मेरे पास एक तीसरी HashMapवस्तु भी है :

HashMap<String, Integer> map3;

मैं कैसे विलय कर सकता हूं map1और map2साथ में map3कैसे?


16
आपने यह नहीं बताया कि यदि आप दोनों मानचित्रों में कोई कुंजी मौजूद है तो आप क्या करना चाहते हैं।
माइकल स्कीपर

जवाबों:


344
map3 = new HashMap<>();

map3.putAll(map1);
map3.putAll(map2);

1
धन्यवाद, मैं मैप्स को एक लूप में मर्ज कर रहा हूं जो एक विधि का उपयोग करता है एक मैप लौटाता है और इसे दूसरे मैप में मर्ज करने की आवश्यकता होती है और एक ही विधि एगियन लागू होती है। इसके लिए, मुझे पुट विधि के साथ अशक्त सूचक अपवाद मिलता है। यह कोशिश / पकड़ ब्लॉक का उपयोग करने में मदद नहीं करता है। मुझे क्या करना चाहिए? मैं लागू कर रहा हूँ अगर हालत, कि अगर आकार == ओ तो putAll लागू नहीं करते हैं और इसे लागू करें और इतने पर ....
Mavin

1
यदि आपको एक एनपीई मिलता है, तो जाहिर है आपने अपनी किसी भी वस्तु को ठीक से इनिशियलाइज़ नहीं किया है। क्या आप स्टैकट्रेस को कैच ब्लॉक में प्रिंट करते हैं? तो आप जानते हैं कि समस्या कहां उत्पन्न होती है। लेकिन जब तक आप स्टैक ट्रेस सहित पूर्ण और सटीक कोड पोस्ट नहीं करते हैं, आपको उस ट्रैक को अपने दम पर ट्रैक करने की आवश्यकता होगी।
a_horse_with_no_name

95
ध्यान दें, इस समाधान के साथ, यदि कोई कुंजी दोनों मानचित्रों में मौजूद है, तो map2 में मान संरक्षित किया जाएगा और map1 में मान खो जाएगा।
माइकल शेपर

5
@MichaelScheper: और क्या उम्मीद करते हैं? कुंजी में एक Mapपरिभाषा के द्वारा अद्वितीय हैं
a_horse_with_no_name

42
मुझे नहीं पता कि ओपर को क्या उम्मीद है। हो सकता है कि वह मैप 1 मानों की अपेक्षा रखता है कि पूर्वता है, या एक अपवाद को फेंक दिया जाए, या कुछ 'विलय' ऑपरेशन के लिए इंटर्जेक्टर्स पर प्रदर्शन किया जाए। या हो सकता है, चूंकि यह एक शुरुआत का सवाल है, यह एक ऐसा मामला है जिसे ओपर ने नहीं माना था, इस मामले में मेरी टिप्पणी उम्मीद के मुताबिक मददगार होगी।
माइकल शेपर

109

यदि आप जानते हैं कि आपके पास डुप्लिकेट कुंजियाँ नहीं हैं, या आप डुप्लिकेट कुंजियों के मानों map2को अधिलेखित करने के लिए मान चाहते हैं map1, तो आप बस लिख सकते हैं

map3 = new HashMap<>(map1);
map3.putAll(map2);

यदि आपको अधिक नियंत्रण की आवश्यकता है कि मूल्यों को कैसे जोड़ा जाता है, तो आप Map.mergeजावा 8 में जोड़ा जा सकता है , जो BiFunctionडुप्लिकेट कुंजियों के मूल्यों को मर्ज करने के लिए उपयोगकर्ता द्वारा प्रदान किया गया है। mergeव्यक्तिगत कुंजी और मूल्यों पर काम करता है, इसलिए आपको एक लूप या उपयोग करने की आवश्यकता होगी Map.forEach। यहां हम डुप्लिकेट कुंजियों के लिए स्ट्रिंग्स को बदलते हैं:

map3 = new HashMap<>(map1);
for (Map.Entry<String, String> e : map2.entrySet())
    map3.merge(e.getKey(), e.getValue(), String::concat);
//or instead of the above loop
map2.forEach((k, v) -> map3.merge(k, v, String::concat));

यदि आप जानते हैं कि आपके पास डुप्लिकेट कुंजियाँ नहीं हैं और इसे लागू करना चाहते हैं, तो आप मर्ज फ़ंक्शन का उपयोग कर सकते हैं AssertionError:

map2.forEach((k, v) ->
    map3.merge(k, v, (v1, v2) ->
        {throw new AssertionError("duplicate values for key: "+k);}));

इस विशिष्ट प्रश्न से एक कदम पीछे लेते हुए, जावा 8 स्ट्रीम लाइब्रेरी प्रदान करता है toMapऔर groupingBy कलेक्टरों । यदि आप बार-बार मानचित्रों को लूप में विलय कर रहे हैं, तो आप स्ट्रीम का उपयोग करने के लिए अपनी गणना का पुनर्गठन करने में सक्षम हो सकते हैं, जो आपके कोड को स्पष्ट कर सकता है और समानांतर धारा और समवर्ती कलेक्टर का उपयोग करके आसान समानता को सक्षम कर सकता है।


46

जावा 8 स्ट्रीम एपीआई का उपयोग कर एक-लाइनर:

map3 = Stream.of(map1, map2).flatMap(m -> m.entrySet().stream())
       .collect(Collectors.toMap(Entry::getKey, Entry::getValue))

इस पद्धति के लाभों में एक मर्ज फ़ंक्शन को पारित करने की क्षमता है, जो उन मानों से निपटेगा जिनके पास एक ही कुंजी है, उदाहरण के लिए:

map3 = Stream.of(map1, map2).flatMap(m -> m.entrySet().stream())
       .collect(Collectors.toMap(Entry::getKey, Entry::getValue, Math::max))

1
यह डुप्लिकेट कुंजियों के लिए IllegalStateException को फेंक देगा
अर्पित जे।

1
@ArpitJ। यह दूसरी भिन्नता का पूरा बिंदु है। कभी-कभी आप अपवाद चाहते हैं, कभी-कभी आप नहीं करते हैं।
एलेक्स आर।

36

दो मानचित्रों के विलय के लिए जावा 8 वैकल्पिक वन-लाइनर:

defaultMap.forEach((k, v) -> destMap.putIfAbsent(k, v));

विधि संदर्भ के साथ भी:

defaultMap.forEach(destMap::putIfAbsent);

या तीसरे नक्शे के साथ मूल नक्शे समाधान के लिए बेरोजगार:

Map<String, Integer> map3 = new HashMap<String, Integer>(map2);
map1.forEach(map3::putIfAbsent);

और यहाँ दो मानचित्रों को तेजी से अपरिवर्तनीय में अमरूद के साथ मिलाने का एक तरीका है जो कम से कम मध्यवर्ती प्रतिलिपि संचालन करता है:

ImmutableMap.Builder<String, Integer> builder = ImmutableMap.<String, Integer>builder();
builder.putAll(map1);
map2.forEach((k, v) -> {if (!map1.containsKey(k)) builder.put(k, v);});
ImmutableMap<String, Integer> map3 = builder.build();

मामलों के लिए जावा 8 के साथ दो मानचित्रों को भी देखें जब दोनों मानचित्रों में मौजूद मानों को मैपिंग फ़ंक्शन के साथ जोड़ा जाना चाहिए।


32

यदि आपको अपने अंतिम मानचित्र के लिए परिवर्तनशीलता की आवश्यकता नहीं है, तो अमरूद की ImmutableMap इसकी विधिBuilder और putAllविधि है , जो जावा के Mapइंटरफ़ेस विधि के विपरीत है , जंजीर हो सकती है।

उपयोग का उदाहरण:

Map<String, Integer> mergeMyTwoMaps(Map<String, Integer> map1, Map<String, Integer> map2) {
  return ImmutableMap.<String, Integer>builder()
      .putAll(map1)
      .putAll(map2)
      .build();
}

बेशक, यह विधि अधिक सामान्य हो सकती है, putAll Mapsतर्कों आदि से varargs और लूप का उपयोग कर सकती है, लेकिन मैं एक अवधारणा दिखाना चाहता था।

इसके अलावा, ImmutableMapऔर इसकी Builderकुछ सीमाएँ हैं (या शायद सुविधाएँ?):

  • वे अशक्त शत्रु हैं (फेंकें NullPointerException- यदि मानचित्र में कोई कुंजी या मान शून्य है)
  • बिल्डर डुप्लिकेट कुंजियों को स्वीकार नहीं करता है ( IllegalArgumentExceptionयदि डुप्लिकेट कुंजियों को जोड़ा गया है तो फेंकता है )।


21

आप इस्तेमाल कर सकते हैं Collection.addAll () अन्य प्रकार, उदाहरण के लिए List, Setआदि के लिए Map, आप उपयोग कर सकते हैं putAll


11

दो मानचित्रों के संयोजन के लिए सामान्य समाधान जो संभवतः आम कुंजियाँ साझा कर सकते हैं:

जगह में:

public static <K, V> void mergeInPlace(Map<K, V> map1, Map<K, V> map2,
        BinaryOperator<V> combiner) {
    map2.forEach((k, v) -> map1.merge(k, v, combiner::apply));
}

एक नया नक्शा लौटना:

public static <K, V> Map<K, V> merge(Map<K, V> map1, Map<K, V> map2,
        BinaryOperator<V> combiner) {
    Map<K, V> map3 = new HashMap<>(map1);
    map2.forEach((k, v) -> map3.merge(k, v, combiner::apply));
    return map3;
}

2

एक छोटा सा स्निपेट जिसका उपयोग मैं अक्सर अन्य मानचित्रों से नक्शा बनाने के लिए करता हूं:

static public <K, V> Map<K, V> merge(Map<K, V>... args) {
    final Map<K, V> buffer = new HashMap<>();

    for (Map m : args) {
        buffer.putAll(m);
    }

    return buffer;
}

2

आप HashMap<String, List<Integer>>दोनों हैशमैप को मर्ज करने और एक ही कुंजी के साथ युग्मित तत्वों को खोने से बचने के लिए उपयोग कर सकते हैं ।

HashMap<String, Integer> map1 = new HashMap<>();
HashMap<String, Integer> map2 = new HashMap<>();
map1.put("key1", 1);
map1.put("key2", 2);
map1.put("key3", 3);
map2.put("key1", 4);
map2.put("key2", 5);
map2.put("key3", 6);
HashMap<String, List<Integer>> map3 = new HashMap<>();
map1.forEach((str, num) -> map3.put(str, new ArrayList<>(Arrays.asList(num))));
//checking for each key if its already in the map, and if so, you just add the integer to the list paired with this key
for (Map.Entry<String, Integer> entry : map2.entrySet()) {
    Integer value = entry.getValue();
    String key = entry.getKey();
    if (map3.containsKey(key)) {
        map3.get(key).add(value);
    } else {
        map3.put(key, new ArrayList<>(Arrays.asList(value)));
    }
}
map3.forEach((str, list) -> System.out.println("{" + str + ": " + list + "}"));

उत्पादन:

{key1: [1, 4]}
{key2: [2, 5]}
{key3: [3, 6]}

2

बहुत देर से लेकिन मुझे वही करने दिया जो मैंने उसी मुद्दे पर किया था।

Map<String, List<String>> map1 = new HashMap<>();
map1.put("India", Arrays.asList("Virat", "Mahi", "Rohit"));
map1.put("NZ", Arrays.asList("P1","P2","P3"));

Map<String, List<String>> map2 = new HashMap<>();
map2.put("India", Arrays.asList("Virat", "Mahi", "Rohit"));
map2.put("NZ", Arrays.asList("P1","P2","P4"));

Map<String, List<String>> collect4 = Stream.of(map1, map2)
                .flatMap(map -> map.entrySet().stream())
                .collect(
                        Collectors.toMap(
                                Map.Entry::getKey,
                                Map.Entry::getValue,
                                (strings, strings2) -> {
                                    List<String> newList = new ArrayList<>();
                                    newList.addAll(strings);
                                    newList.addAll(strings2);
                                    return newList;
                                }
                        )
                );
collect4.forEach((s, strings) -> System.out.println(s+"->"+strings));

यह निम्न आउटपुट देता है

NZ->[P1, P2, P3, P1, P2, P4]
India->[Virat, Mahi, Rohit, Virat, Mahi, Rohit]

0
    HashMap<Integer,String> hs1 = new HashMap<>();
    hs1.put(1,"ram");
    hs1.put(2,"sita");
    hs1.put(3,"laxman");
    hs1.put(4,"hanuman");
    hs1.put(5,"geeta");

    HashMap<Integer,String> hs2 = new HashMap<>();
    hs2.put(5,"rat");
    hs2.put(6,"lion");
    hs2.put(7,"tiger");
    hs2.put(8,"fish");
    hs2.put(9,"hen");

    HashMap<Integer,String> hs3 = new HashMap<>();//Map is which we add

    hs3.putAll(hs1);
    hs3.putAll(hs2);

    System.out.println(" hs1 : " + hs1);
    System.out.println(" hs2 : " + hs2);
    System.out.println(" hs3 : " + hs3);

डुप्लिकेट आइटम नहीं जोड़े जाएंगे (यानी डुप्लिकेट कीज़) जब हम hs3 प्रिंट करेंगे तो हमें कुंजी 5 के लिए केवल एक मान मिलेगा जो कि अंतिम मान जोड़ा जाएगा और यह चूहा होगा। ** [सेट में डुप्लिकेट कुंजी की अनुमति नहीं देने की संपत्ति है, लेकिन मूल्य डुप्लिकेट हो सकते हैं]


0

विधि 1: एक सूची में नक्शे डालें और फिर शामिल हों

public class Test15 {
public static void main(String[] args) {

    Map<String, List<String>> map1 = new HashMap<>();
    map1.put("London", Arrays.asList("A", "B", "C"));
    map1.put("Wales", Arrays.asList("P1", "P2", "P3"));

    Map<String, List<String>> map2 = new HashMap<>();
    map2.put("Calcutta", Arrays.asList("Protijayi", "Gina", "Gini"));
    map2.put("London", Arrays.asList( "P4", "P5", "P6"));
    map2.put("Wales", Arrays.asList( "P111", "P5555", "P677666"));

    System.out.println(map1);System.out.println(map2);



    // put the maps in an ArrayList

    List<Map<String, List<String>>> maplist = new ArrayList<Map<String,List<String>>>();
    maplist.add(map1);
    maplist.add(map2);
    /*
<T,K,U> Collector<T,?,Map<K,U>> toMap(

                                  Function<? super T,? extends K> keyMapper,

                                  Function<? super T,? extends U> valueMapper,

                                  BinaryOperator<U> mergeFunction)
    */

 Map<String, List<String>> collect = maplist.stream()
    .flatMap(ch -> ch.entrySet().stream())
    .collect(
            Collectors.toMap(

            //keyMapper,

            Entry::getKey,

            //valueMapper
            Entry::getValue,

            // mergeFunction
     (list_a,list_b) -> Stream.concat(list_a.stream(), list_b.stream()).collect(Collectors.toList())

            ));



    System.out.println("Final Result(Map after join) => " + collect);
    /*
    {Wales=[P1, P2, P3], London=[A, B, C]}
{Calcutta=[Protijayi, Gina, Gini], Wales=[P111, P5555, P677666], London=[P4, P5, P6]}
Final Result(Map after join) => {Calcutta=[Protijayi, Gina, Gini], Wales=[P1, P2, P3, P111, P5555, P677666], London=[A, B, C, P4, P5, P6]}
*/

}//main


}

विधि 2: सामान्य मैप मर्ज

public class Test15 {
public static void main(String[] args) {

    Map<String, List<String>> map1 = new HashMap<>();
    map1.put("London", Arrays.asList("A", "B", "C"));
    map1.put("Wales", Arrays.asList("P1", "P2", "P3"));

    Map<String, List<String>> map2 = new HashMap<>();
    map2.put("Calcutta", Arrays.asList("Protijayi", "Gina", "Gini"));
    map2.put("London", Arrays.asList( "P4", "P5", "P6"));
    map2.put("Wales", Arrays.asList( "P111", "P5555", "P677666"));

    System.out.println(map1);System.out.println(map2);




    /*
<T,K,U> Collector<T,?,Map<K,U>> toMap(

                                  Function<? super T,? extends K> keyMapper,

                                  Function<? super T,? extends U> valueMapper,

                                  BinaryOperator<U> mergeFunction)
    */


Map<String, List<String>> collect = Stream.of(map1,map2)
    .flatMap(ch -> ch.entrySet().stream())
    .collect(
            Collectors.toMap(

            //keyMapper,

            Entry::getKey,

            //valueMapper
            Entry::getValue,

            // mergeFunction
     (list_a,list_b) -> Stream.concat(list_a.stream(), list_b.stream()).collect(Collectors.toList())

            ));



    System.out.println("Final Result(Map after join) => " + collect);
    /*
    {Wales=[P1, P2, P3], London=[A, B, C]}
{Calcutta=[Protijayi, Gina, Gini], Wales=[P111, P5555, P677666], London=[P4, P5, P6]}
Final Result(Map after join) => {Calcutta=[Protijayi, Gina, Gini], Wales=[P1, P2, P3, P111, P5555, P677666], London=[A, B, C, P4, P5, P6]}

*/

}//main


}

0

आप मानचित्र के लिए putAll फ़ंक्शन का उपयोग कर सकते हैं जैसा कि नीचे दिए गए कोड में बताया गया है

HashMap<String, Integer> map1 = new HashMap<String, Integer>();
map1.put("a", 1);
map1.put("b", 2);
map1.put("c", 3);
HashMap<String, Integer> map2 = new HashMap<String, Integer>();
map1.put("aa", 11);
map1.put("bb", 12);
HashMap<String, Integer> map3 = new HashMap<String, Integer>();
map3.putAll(map1);
map3.putAll(map2);
map3.keySet().stream().forEach(System.out::println);
map3.values().stream().forEach(System.out::println);

0

नीचे स्निपेट एक से अधिक मानचित्र लेता है और उन्हें संयोजित करता है।

 private static <K, V> Map<K, V> combineMaps(Map<K, V>... maps) {
        if (maps == null || maps.length == 0) {
            return Collections.EMPTY_MAP;
        }

        Map<K, V> result = new HashMap<>();

        for (Map<K, V> map : maps) {
            result.putAll(map);
        }
        return result;
    }

डेमो उदाहरण लिंक।


-1

आप का उपयोग कर सकते हैं - addAll विधि

http://download.oracle.com/javase/6/docs/api/java/util/HashMap.html

लेकिन हमेशा यह मुद्दा होता है कि - यदि आपके दो हैश मानचित्रों के पास कोई कुंजी है - तो यह दूसरे हैश मानचित्र से कुंजी के मूल्य के साथ पहले हैश मानचित्र से कुंजी के मूल्य को ओवरराइड करेगा।

सुरक्षित पक्ष पर होने के लिए - प्रमुख मान बदलें - आप कुंजी पर उपसर्ग या प्रत्यय का उपयोग कर सकते हैं - (पहले हैश मानचित्र के लिए अलग उपसर्ग / प्रत्यय और दूसरे हैश मानचित्र के लिए अलग उपसर्ग / प्रत्यय)

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