[java] 동일한 유형을 포함하는 두 개의 HashMap 객체를 결합하려면 어떻게해야합니까?

HashMap다음과 같이 정의 된 두 개의 객체 가 있습니다 .

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

또한 세 번째 HashMap객체가 있습니다.

HashMap<String, Integer> map3;

어떻게 병합 할 수 있습니다 map1map2에 함께 map3?



답변

map3 = new HashMap<>();

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


답변

중복 키가 없거나 중복 키의 값 map2을 덮어 쓰려는 값을 알고 싶다면 map1간단히 쓸 수 있습니다.

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

값을 결합하는 방법에 대해 더 많은 제어가 필요한 경우 Map.mergeJava 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다음 을 throw하는 병합 기능을 사용할 수 있습니다 .

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

이 특정 질문에서 한 걸음 물러 나면 Java 8 스트림 라이브러리는 toMapgroupingBy 수집기를 제공합니다 . 반복적으로 맵을 루프로 병합하는 경우 스트림을 사용하도록 계산을 재구성 할 수 있습니다. 이로 인해 코드를 명확하게하고 병렬 스트림과 동시 수집기를 사용하여 쉽게 병렬 처리 할 수 ​​있습니다.


답변

Java 8 Stream API를 사용한 원 라이너 :

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 대체 1- 라이너 :

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과 함께 두 맵 병합을 참조하십시오 .


답변

당신이 당신의 마지막지도에 대한 가변성이 필요하지 않은 경우,이 구아바의 ImmutableMap 그것과 BuilderputAll방법을 달리하는, 자바의 Map인터페이스 방법 , 체인 될 수있다.

사용 예 :

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

물론이 방법은보다 일반적이며 varargs를 사용하고 putAll Maps인수 등을 반복 할 수 는 있지만 개념을 보여주고 싶었습니다.

또한, ImmutableMap과는 Builder몇 가지 한계를 가지고 (또는 어쩌면 특징?) :

  • 그들은 적대적입니다 ( NullPointerException지도에있는 키 또는 값이 null 인 경우 던져 )
  • 빌더는 중복 키를 허용하지 않습니다 ( IllegalArgumentException중복 키가 추가 된 경우 발생).

답변

해시 맵에는 putAll 메소드가 있습니다.

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


답변

당신은 사용할 수 Collection.addAll ()를 예를 들어 다른 유형에 대한 List, Set, 등이 Map, 당신이 사용할 수 있습니다 putAll.