【问题标题】:Merging Two HashMaps With Duplicate Keys and Update Value合并两个具有重复键和更新值的 HashMap
【发布时间】:2021-06-22 06:38:54
【问题描述】:

我有两个 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.

【问题讨论】:

  • "具有相同键的实例应存储为相同的 MyObject" - 如果实例具有相同的键,您希望如何选择要存储的 MyObject 的哪个实例?
  • 存储哪个 MyObject 实例无关紧要,无论如何都不是针对这个特定问题。
  • 合并时添加两个对象的计数器?

标签: java merge hashmap


【解决方案1】:

你可以这样做:

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

创建一些数据

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

【讨论】:

    【解决方案2】:

    您必须设置您创建的新MyObjectcounter 值。

    如果MyObject 类有一个setter,

    Map<String, MyObject> map3 = new HashMap<>(map1);
    
    map2.forEach((key, value) -> map3.merge(key, value, (v1, v2) -> {
            MyObject myObject = new MyObject(v1.getName());
            myObject.setCounter(v1.getCounter() + v2.getCounter());
            return myObject;
    }));
    

    如果你有一个接受名称和计数器的重载构造函数,

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

    然后,你可以这样做,

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-17
      • 2013-02-26
      • 2016-07-19
      • 2018-08-03
      • 2014-11-13
      相关资源
      最近更新 更多