比较两张地图 [英] Comparing two maps

查看:134
本文介绍了比较两张地图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个映射声明为 Map< String,Object> 。这里的 Object 可能是另一个 Map< String,Object> (等等)。我想检查两个地图是否完全一样,不知道他们的深度。而不是使用递归,我可以比较每个地图上调用的 toString()的输出吗?或者是比较简单的地图吗?

I have two maps declared as Map<String, Object>. The Object here could be another Map<String, Object> (and so on). I want to check if two maps are exactly the same without knowing their depth. Instead of using recursion can I compare the output of the toString() called on each map? Or is there a simpler way to compare the maps?

推荐答案

快速回答



您应该使用等于方法,因为这是执行您想要的比较。 toString()本身使用一个迭代器,就像等于,但是效率更低。另外,由于@Teepeemm指出, toString 受到元素顺序(基本上是迭代器返回顺序)的影响,因此不能为两个不同的地图提供相同的输出(特别是如果我们比较两个不同的地图)。

Quick Answer

You should use the equals method since this is implemented to perform the comparison you want. toString() itself uses an iterator just like equals but is a more inefficient approach. Additionally, as @Teepeemm pointed out toString is affected by order of elements (basically iterator return order) and hence is not gauranteed to provide same output for 2 different maps (especially if we compare two different maps).

注意/警告:您的问题和答案假定实现地图界面的类似于 toString 等于行为。默认的java类是这样做的,但是需要检查自定义地图类以验证预期的行为。

Note/Warning: Your question and my answer assumes that classes implementing the map interface respect expected toString and equals behavior. The default java classes do so, but a custom map class needs to be examined to verify expected behavior.

请参阅: http ://docs.oracle.com/javase/7/docs/api/java/util/Map.html

boolean equals(Object o)




将指定的对象与此对比地图平等。如果给定的对象也是地图,并且两个地图表示相同的
映射
,则返回true
。如果m1.entrySet()。equals(m2.entrySet()),则更正式地,两个映射m1和m2表示相同的
映射。这确保
equals方法在
Map接口的不同实现中正常工作。

Compares the specified object with this map for equality. Returns true if the given object is also a map and the two maps represent the same mappings. More formally, two maps m1 and m2 represent the same mappings if m1.entrySet().equals(m2.entrySet()). This ensures that the equals method works properly across different implementations of the Map interface.



Java中的实现Source(java.util.AbstractMap)



此外,java本身负责迭代所有元素,进行比较,所以你不必。看看 HashMap 之类的类使用的 AbstractMap 的实现:

Implementation in Java Source (java.util.AbstractMap)

Additionally, java itself takes care of iterating through all elements and making the comparison so you don't have to. Have a look at the implementation of AbstractMap which is used by classes such as HashMap:

 // Comparison and hashing

    /**
     * Compares the specified object with this map for equality.  Returns
     * <tt>true</tt> if the given object is also a map and the two maps
     * represent the same mappings.  More formally, two maps <tt>m1</tt> and
     * <tt>m2</tt> represent the same mappings if
     * <tt>m1.entrySet().equals(m2.entrySet())</tt>.  This ensures that the
     * <tt>equals</tt> method works properly across different implementations
     * of the <tt>Map</tt> interface.
     *
     * <p>This implementation first checks if the specified object is this map;
     * if so it returns <tt>true</tt>.  Then, it checks if the specified
     * object is a map whose size is identical to the size of this map; if
     * not, it returns <tt>false</tt>.  If so, it iterates over this map's
     * <tt>entrySet</tt> collection, and checks that the specified map
     * contains each mapping that this map contains.  If the specified map
     * fails to contain such a mapping, <tt>false</tt> is returned.  If the
     * iteration completes, <tt>true</tt> is returned.
     *
     * @param o object to be compared for equality with this map
     * @return <tt>true</tt> if the specified object is equal to this map
     */
    public boolean equals(Object o) {
        if (o == this)
            return true;

        if (!(o instanceof Map))
            return false;
        Map<K,V> m = (Map<K,V>) o;
        if (m.size() != size())
            return false;

        try {
            Iterator<Entry<K,V>> i = entrySet().iterator();
            while (i.hasNext()) {
                Entry<K,V> e = i.next();
                K key = e.getKey();
                V value = e.getValue();
                if (value == null) {
                    if (!(m.get(key)==null && m.containsKey(key)))
                        return false;
                } else {
                    if (!value.equals(m.get(key)))
                        return false;
                }
            }
        } catch (ClassCastException unused) {
            return false;
        } catch (NullPointerException unused) {
            return false;
        }

        return true;
    }



比较两种不同类型的地图


$ b比较一个 TreeMap HashMap toString $ c>虽然等于正确比较内容。

Comparing two different types of Maps

toString fails miserably when comparing a TreeMap and HashMap though equals does compare contents correctly.

代码

public static void main(String args[]) {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("2", "whatever2");
map.put("1", "whatever1");
TreeMap<String, Object> map2 = new TreeMap<String, Object>();
map2.put("2", "whatever2");
map2.put("1", "whatever1");

System.out.println("Are maps equal (using equals):" + map.equals(map2));
System.out.println("Are maps equal (using toString().equals()):"
        + map.toString().equals(map2.toString()));

System.out.println("Map1:"+map.toString());
System.out.println("Map2:"+map2.toString());
}

输出:

Are maps equal (using equals):true
Are maps equal (using toString().equals()):false
Map1:{2=whatever2, 1=whatever1}
Map2:{1=whatever1, 2=whatever2}

这篇关于比较两张地图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆