当前位置: 首页 > 知识库问答 >
问题:

如何在java中接收地图的差异?

牧宁
2023-03-14

我有两张地图:

Map<String, Object> map1;
Map<String, Object> map2;

我需要得到这些地图之间的差异。是否存在可能是apache utils如何接收这种差异?目前,似乎需要获取每个映射的条目集,并找到diff1=set1-set2和diff2=set2-set1。创建摘要映射=diff1 diff2之后,它看起来非常笨拙。存在另一种方式吗?谢谢

共有3个答案

范朗
2023-03-14

如果我理解的很好的话,你是在试图计算两个映射项集之间的对称差。

Map<String, Object> map1;
Map<String, Object> map2;

Set<Entry<String, Object>> diff12 = new HashSet<Entry<String, Object>>(map1.entrySet());
Set<Entry<String, Object>> diff21 = new HashSet<Entry<String, Object>>(map2.entrySet());
Set<Entry<String, Object>> result;

diff12.removeAll(map2.entrySet());
diff21.removeAll(map1.entrySet());
diff12.addAll(diff21);

考虑到你提到的尴尬行为,让我们仔细看看上面的代码行为。例如,如果我们从上面给定的链接中选取数值示例:

Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("a", 1);
map1.put("b", 2);
map1.put("c", 3);
map1.put("d", 4);

Map<String, Object> map2 = new HashMap<String, Object>();
map2.put("a", 1);    
map2.put("d", 4);
map2.put("e", 5);

如图所示计算差异后,输出:

System.out.println(Arrays.deepToString(diff12.toArray()));

给出:

[e=5, c=3, b=2]

这是正确的结果。但是,如果我们这样做:

public class CustomInteger {
    public int val;

    public CustomInteger(int val) {
        this.val = val;
    }

    @Override
    public String toString() {
        return String.valueOf(val);
    }        
}   

map1.put("a", new CustomInteger(1));
map1.put("b", new CustomInteger(2));
map1.put("c", new CustomInteger(3));
map1.put("d", new CustomInteger(4));

map2.put("a", new CustomInteger(1));    
map2.put("d", new CustomInteger(4));
map2.put("e", new CustomInteger(5));

同样的算法给出了以下输出:

[e=5, a=1, d=4, d=4, b=2, a=1, c=3]

这是不正确的(可能会被描述为尴尬:)

在第一个示例中,映射被int值填充,并且被自动装箱为整数值。

Integer类有自己的equals和hashCode方法实现。

CustomInteger类没有实现这些方法,因此它从omnipresent对象类继承了这些方法。

Set接口中removeAll方法的API文档说明如下:

从该集合中移除其所有包含在指定集合中的元素(可选操作)。如果指定集合也是一个集合,则此操作有效地修改该集合,使其值为两个集合的非对称集差。

为了确定两个集合中包含哪些元素,RemveAll方法使用集合元素的equals方法。

这就是问题所在:如果两个数值相同,Integer的equals方法将返回true,而Object的equals方法仅当它是同一个对象时才会返回true,例如:

Integer a = 1; //autoboxing
Integer b = new Integer(1);
Integer c = 2;

a.equals(b); //  true
a.equals(c); //  false

CustomInteger d = new CustomInteger(1);
CustomInteger e = new CustomInteger(1);
CustomInteger f = new CustomInteger(2);

d.equals(e); //false
d.equals(f) // false

d.val == e.val //true
d.val == f.val //false

如果仍然有点模糊,我强烈建议阅读以下教程:

刘承运
2023-03-14

下面是一个简单的片段,你可以用它来代替巨大的番石榴库:

public static <K, V> Map<K, V> mapDifference(Map<? extends K, ? extends V> left, Map<? extends K, ? extends V> right) {
    Map<K, V> difference = new HashMap<>();
    difference.putAll(left);
    difference.putAll(right);
    difference.entrySet().removeAll(right.entrySet());
    return difference;
}

查看整个工作示例

琴琪
2023-03-14

谷歌番石榴怎么样?:

Maps.difference(map1,map2)
 类似资料:
  • 问题内容: 我有两张地图: 我需要接收这些地图之间的差异。是否存在可能是apache utils如何获得此差异?现在看来,需要获取每个映射的条目集,并找到diff1 = set1-set2和diff2 = set2- set1。创建摘要映射后= diff1 + diff2看起来很尴尬。是否存在其他方式?谢谢。 问题答案: 如何谷歌番石榴?

  • 问题内容: 如何在Java Spring框架中注入Map?如果可能,请提供一些示例代码。 以下合法吗? 问题答案: 首先在您的内定义这样的地图: 然后像这样在您的任何bean中使用此Map:

  • 是的,它只显示1项。 请帮我拿到所有的,不仅仅是1

  • 我试图在Java创建一个地图,但失败了。 它告诉我在行的末尾需要或,但是,当我尝试其中一个时,我会收到错误。 将告诉我“映射是抽象的;无法实例化” 将告诉我“应为数组初始值设定项” 我对编码还不太熟悉,所以请对我友好一点,多多忍耐:)

  • 问题内容: 我需要一个数据结构来以1:1关系存储string-int值对,并且也能够从任何一种方式查找它们的对应对象。 我编写了一个带有Hashtable和String数组的类,并将数据存储了2次,并使用内置函数进行查找。 我的问题是,有没有更好的方法可以做到这一点?更好的是,我的意思是要高效并且不存储2次数据,并且最好不要编写任何代码:P。 问题答案: 看来您可能正在寻找bimap。 Googl

  • 问题内容: 我想从19:00:00中减去两个时间段,例如16:00:00。是否有任何Java函数?结果可以是毫秒,秒或分钟。 问题答案: 差异以毫秒为单位。