首页 > 解决方案 > 合并两个具有重复键和更新值的 HashMap

问题描述

我有两个 HashMap,它们的键是 String,值是 MyObject。我的目标是合并这两个哈希图,然后返回一个包含所有对象的哈希图到映射。但如果键(字符串)相同,则具有相同键的实例应存储为相同的 MyObject。我已经成功地做到了这一点。

我的问题是我想用相同的键更新实例内的字段。

class MyObject
String name;
int counter;

MyObject(String name) {
this.name = name;
this.counter = 1;
}

// getters and setters...

我的目标是每次哈希图中的键相同时更新 int 计数器。

这段代码将成功合并这两个映射,我似乎无法找到每次 MyObject 具有相同键时如何更新 MyObject 中的字段 int 计数器。

class Main
HashMap<String, MyObject> map1 = new HashMap<>();
HashMap<String, MyObject> map2 = new HashMap<>();

//some code that will put some instances of MyObject into map1 and map2
// assume that least three instances have the same keys

HashMap<String, MyObject> map3 = new HashMap<>(map1);

map2.forEach((key, value) -> map3.merge(key, value, (v1, v2) -> new MyObject(v1.getName())));

假设这两个对象有相同的键;

MyObject.getCounter() = 3 in map1

MyObject.getCounter() = 5 in map2

The new MyObject.getCounter() should be 8.

标签: javamergehashmap

解决方案


你可以这样做:

  • 流式传输两个条目集。
  • 收集到地图
  • 并在合并方法中添加它们

创建一些数据

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

map1.put("A", new MyObject(2));
map1.put("B", new MyObject(4));
map1.put("C", new MyObject(10));
map2.put("C", new MyObject(10));
map2.put("B", new MyObject(8));

现在创建地图

Map<String, MyObject> result = Stream
        .concat(map1.entrySet().stream(),
                map2.entrySet().stream())
        .collect(Collectors.toMap(Entry::getKey,
                Entry::getValue, (a, b) -> {
                    a.setCounter(a.getCounter() + b.getCounter());
                    return a;
                }, HashMap::new));

result.entrySet().forEach(System.out::println);

印刷

A=2
B=12
C=20

您也可以在收集之前使用以下内容。

        Map<String, MyObject> result = Stream.of(map1,map2)
                .flatMap(map->map.entrySet().stream())
                .collect(...);

类定义

    
 class MyObject {
    
    int value;
    public MyObject(int v) {
        this.value = v;
    }
    public int getCounter() {
        return value;
    }
    
    public void setCounter(int a) {
        value = a;
    }
    
    public String toString() {
        return value + "";
    }
}

推荐阅读