【问题标题】:How to get the difference of two maps based on the key set? [duplicate]如何根据密钥集获取两张地图的差异? [复制]
【发布时间】:2014-05-03 14:12:19
【问题描述】:

我有两张地图:

Map<String, Sample> newMap = convertJSONObjectToSampleMap(newMapStr);
Map<String, Sample> oldMap = convertJSONObjectToSampleMap(oldMapStr);

Sample 是一些自定义类

newMap 有键:[1,2,3,4,5] oldMap 有键:[2,3,4,5,8]

获得它们之间差异的最佳方法是什么,例如,使用密钥获取Samples:18

我想使用Collections 并提取Set&lt;&gt;

Set<String> newSet = newMap.keySet();
Set<String> oldSet = oldMap.keySet();

谢谢你,

【问题讨论】:

标签: java collections map set-difference


【解决方案1】:

你想要的叫做对称差。

Guava 提供了这样的方法。

Set<String> diff = Sets.symmetricDifference(newSet, oldSet);

然后只需遍历集合即可获取样本。

List<Sample> samples = new ArrayList<>();
for(String key : diff){
    if(oldMap.containsKey(key)){
        samples.add(oldMap.get(key));
    } else {
        samples.add(newMap.get(key));
    }
}

你也可以用官方的API来做,基本上对称的区别是并集减去两个集合的交集,但是为什么要重新发明轮子呢?

如果您只使用一种方法,则使用外部依赖可能会很糟糕,但 Guava 提供了许多必须的有用功能。

【讨论】:

  • -1 这个答案引入了对您的项目的外部依赖。
  • @ErickRobertson 当然你可以使用官方的 JDK,但是 Guava 确实是必须的,我看不出有什么理由不使用外部库来做这类事情。
  • 问题是如何获取地图的values,而不仅仅是keys,还需要添加一个步骤来获取这些key。
  • @AVolpe 你是对的,固定的。
  • 这里没有任何收获。您仍然必须在代码中围绕 containsKey 进行循环,而且效率较低。我不同意“番石榴确实是必须的”。
【解决方案2】:

遍历一张地图并进行比较。

只有O(n) 可以循环浏览其中一张地图。考虑这段代码:

for (String key: oldMap.keySet()) {
    if (newMap.containsKey(key))
        newMap.remove(key);
    else
        newMap.put(key, oldMap.get(key));
}

newMap 现在将只包含两个集合中的唯一条目。它为您提供键和值,因此所有数据都在一个地方。它很快,因为您只需要遍历其中一张地图中的键,而不必创建集合。

【讨论】:

  • newMap.keySet().removeAll(oldMap.keySet()) 我想这要简单得多,不是吗?
  • @allprog 那么您将拥有来自newMap 的密钥在oldMap 中找不到,但您不会拥有仅在oldMap 中的密钥。
  • 啊,好的。我没有考虑else 分支。
【解决方案3】:

如果您只对按键感兴趣,请使用这样的函数:

public static Set<String> getDiff(Map<String,Object> mapA, Map<String,Object> mapB) {
    Set<String> diff = mapA.keySet();
    for (String s: mapB.keySet()) {
        if (diff.contains(s))
            diff.remove(s);
        else
            diff.add(s);
    }
    return diff;
}

对完整的 diff Map 使用以下函数(不影响您现有的 Map 对象):

public static Map<String,Object> getDiff(Map<String,Object> mapA, Map<String,Object> mapB) {
   Map<String,Object> diff = new HashMap<String,Object>();
   diff.putAll(mapA);
   for (String s: mapB.keySet()) {
       if (diff.containsKey(s))
           diff.remove(s);
       else
           diff.put(s, mapB.get(s));
   }
   return diff;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-13
    • 2021-11-10
    • 2013-10-09
    • 1970-01-01
    • 2021-03-31
    • 1970-01-01
    • 1970-01-01
    • 2015-10-31
    相关资源
    最近更新 更多