简体   繁体   English

Java 将两个相同类型的 hashmap 组合成一个新的 hashmap 保持重复

[英]Java combining two hashmaps of the same type into a new hashmap keeping duplicates

Assume we are given:假设我们得到:

Map<String, String> map1 = new HashMap<>();
map1.put("111","Frank");
map1.put("222","Ted");
map1.put("555","Peter");

Map<String, String> map2 = new HashMap<>();
map2.put("333","Roger");
map2.put("222","Ted");
map2.put("888","Kent");
map2.put("555","Peter");

How could I go about combining both of these into a new map:我怎么能 go 将这两者组合成一个新的 map:

Map<String, String> combinedMap = new HashMap<>();

I wanted to do it in a java stream way, so my attempt was:我想以 java stream 的方式来做,所以我的尝试是:

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

But I was hit with some duplicate key error.但是我遇到了一些重复的键错误。 I believe I could also just do a combinedMap.putAll(map1) and combinedMap.putAll(map2) but I'm not sure if that's the best way possible.我相信我也可以做一个combinedMap.putAll(map1)combinedMap.putAll(map2)但我不确定这是否是最好的方法。

You almost had it with your use of a Java stream.使用 Java stream 时,您几乎拥有它。 The only thing you missed that you can provide a "merger function" that takes care of resolving collisions when the same key exists in both maps.您唯一错过的是,您可以提供一个“合并功能”,当两个地图中存在相同的键时,该功能可以解决冲突。 Since it doesn't matter in our case which one we pick, I added a very simple merger that just pick one of them arbitrarily:由于在我们的情况下选择哪一个并不重要,我添加了一个非常简单的合并,只需任意选择其中一个:

combinedMap = Stream.of(map1, map2)
    .flatMap(m -> m.entrySet().stream())
    .collect(Collectors.toMap(
        Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1));

System.out.println(combinedMap);

Results:结果:

{111=Frank, 222=Ted, 333=Roger, 555=Peter, 888=Kent}

If you want to keep duplicates, then Map is not the correct data-structure.如果要保留重复项,则 Map 不是正确的数据结构。 You need something like a MultiMap or Map<String,List<String>> .您需要MultiMapMap<String,List<String>>之类的东西。

An Example:一个例子:

public class Main {

    public static void main(String[] args) {
        System.out.println(combine(Map.of("111", "sam"), Map.of("222", "joe", "111","tim")));
    }

    public static Map<String, List<String>> combine(Map<String, String>... maps) {
        return Arrays.stream(maps).flatMap(m -> m.entrySet().stream())
                .collect(Collectors.toMap(e -> e.getKey(), e -> Arrays.asList(e.getValue()), (v1, v2) -> Stream.of(v1, v2).flatMap(List::stream).collect(Collectors.toList())));
    }
}

If your final HashMap can have multiple entries for a single key, then you must store these entries in some sort of a sequence.如果您的最终 HashMap 可以有多个条目用于单个键,那么您必须以某种顺序存储这些条目。 There is simply no other way around it.根本没有其他方法可以解决它。

As suggested by other users, the previous entry with the same key will be replaced with the new entry if the entry is not a sequence.正如其他用户所建议的,如果条目不是序列,则具有相同键的先前条目将被替换为新条目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM