Programing

동일한 유형을 포함하는 두 개의 HashMap 개체를 결합하려면 어떻게 해야 하는가?

c10106 2022. 5. 22. 11:09
반응형

동일한 유형을 포함하는 두 개의 HashMap 개체를 결합하려면 어떻게 해야 하는가?

난 두 개가 있다.HashMap이와 같이 정의된 개체:

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

나도 3분의 1이 있다.HashMap객체:

HashMap<String, Integer> map3;

병합 방법map1그리고map2로 합쳐서.map3?

map3 = new HashMap<>();

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

것을 중가가나 을의 을 원하는 map2을어치다의 map1중복 키는 그냥 쓰기만 하면 된다.

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

값이 조합되는 방법에 대해 더 많은 통제가 필요한 경우, 사용자가 제공한 것을 사용하는 Java 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이 에서 한 자바 8스튜디오(Java 8 streams Library)에서 자바 8스튜디오를 제공하고 있다.toMap그리고groupingBy 수집가.반복적으로 루프로 지도를 병합하는 경우 스트림을 사용하도록 계산을 재구성할 수 있으며, 이 경우 코드를 명확히 하고 병렬 스트림과 동시 수집기를 사용하여 쉬운 병렬 처리를 가능하게 할 수 있다.

Java 8 Stream API를 사용하는 One-liner:

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))

두 지도를 병합하는 Java 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);

그리고 여기 두 개의 지도를 Guava와 빠른 불변성 맵으로 병합하여 중간 복사 작업을 최소화하는 방법이 있다.

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();

또한 두 맵에 있는 값을 매핑 기능과 결합해야 하는 경우 Java 8과 병합하기를 참조하십시오.

최종 지도에 돌연변이가 필요하지 않다면, 자바의 인터페이스 방식과 대조적으로 체인으로 묶일 수 있는 과바와 방법구아바가 있다.

사용 예:

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

물론, 이 방법은 더 일반적일 수 있다. vargs와 루프를 사용하여putAll Maps논쟁 등으로부터. 하지만 나는 개념을 보여주고 싶었다.

또,ImmutableMap그 밖에Builder제한 사항이 거의 없음(또는 기능):

  • 그들은 완전히 적대적이다.NullPointerException- 지도에서 키 또는 값이 null인 경우)
  • 빌더가 중복 키를 허용하지 않음(행)IllegalArgumentException중복 키가 추가된 경우).

HashMap에는putAll방법의

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

다른 유형(예: Collection.addAll())을 사용할 수 있다.List,Set, 등을 위해Map, 사용할 수 있다.putAll.

공통 키를 공유할 수 있는 두 개의 맵을 결합하기 위한 일반 솔루션:

인플레이스:

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;
}

매우 늦었지만 같은 문제가 생겼을 때 내가 한 일을 공유하게 해줘.

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]

다른 지도에서 지도를 만들기 위해 자주 사용하는 작은 조각:

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;
}

사용할 수 있다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]}

아래 코드에 설명된 대로 지도에 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);

아래 작은 조각은 두 개 이상의 지도를 가져다가 결합한다.

 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;
    }

데모 예제 링크.

다음과 같은 입력을 가정한다.

    import java.util.stream.Stream;
    import java.util.stream.Collectors;
    import java.util.Map;
   
    ...

    var m1 = Map.of("k1", 1, "k2", 2);
    var m2 = Map.of("k3", 3, "k4", 4);

두 입력 맵 사이에 키 충돌이 없어야 하는 경우, 모든 돌연변이를 방지하고 불변의 결과를 산출하는 간단한 표현은 다음과 같을 수 있다.

    var merged = Stream.concat(
        m1.entrySet().stream(),
        m2.entrySet().stream()
    ).collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue));

키 충돌이 가능한 경우, 우리는 램다를 제공하여 중복 제거 방법을 지정할 수 있다.예를 들어, 두 입력에 항목이 있는 경우 가장 큰 값을 유지하려면 다음을 수행하십시오.

    .collect(Collectors.toUnmodifiableMap(
        Map.Entry::getKey,
        Map.Entry::getValue,
        Math::max))  // any function  (Integer, Integer) -> Integer  is ok here
    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에 대해 오직 하나의 값만 얻을 것이고 그것은 쥐가 될 것이기 때문에 중복된 아이템은 추가되지 않을 것이다.**[Set에는 중복 키를 허용하지 않는 속성이 있지만 값은 중복될 수 있음]

방법 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


}
    

파이썬에서는 해시맵을 사전이라고 하는데 우리는 그것들을 아주 쉽게 병합할 수 있다.

x = {'Roopa': 1, 'Tabu': 2}
y = {'Roopi': 3, 'Soudipta': 4}


z = {**x,**y}
print(z)
{'Roopa': 1, 'Tabu': 2, 'Roopi': 3, 'Soudipta': 4}

사용할 수 있음 - addAll 메서드

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

그러나 만약 당신의 두 해시 맵이 같은 키를 가지고 있다면, 그것은 첫번째 해시 맵의 키 값을 두번째 해시 맵의 키 값으로 재정의할 것이라는 문제가 항상 있다.

안전한 쪽에 있는 경우 - 키 값 변경 - 키에 접두사 또는 접미사를 사용할 수 있음 - (첫 번째 해시 맵의 경우 다른 접두사/접미사 및 두 번째 해시 맵의 경우 다른 접두사/접미사)

참조URL: https://stackoverflow.com/questions/4299728/how-can-i-combine-two-hashmap-objects-containing-the-same-types

반응형