比较两张地图
我有两个地图声明为.这里可能是另一个(依此类推)。我想在不知道其深度的情况下检查两张地图是否完全相同。我是否可以比较每个映射上被调用的输出,而不是使用递归?还是有更简单的方法来比较地图?Map<String, Object>
Object
Map<String, Object>
toString()
我有两个地图声明为.这里可能是另一个(依此类推)。我想在不知道其深度的情况下检查两张地图是否完全相同。我是否可以比较每个映射上被调用的输出,而不是使用递归?还是有更简单的方法来比较地图?Map<String, Object>
Object
Map<String, Object>
toString()
您应该使用该方法,因为这是为了实现以执行所需的比较。 它本身使用迭代器就像使用迭代器一样,但它是一种效率更高的方法。此外,正如@Teepeemm指出的那样,受元素顺序(基本上是迭代器返回顺序)的影响,因此不能保证为2个不同的映射提供相同的输出(特别是如果我们比较两个不同的映射)。equals
toString()
equals
toString
注意/警告:您的问题和我的答案假设实现映射接口的类遵循预期和行为。默认的 java 类会这样做,但需要检查自定义映射类以验证预期行为。toString
equals
请参见: 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 接口的不同实现中正常工作。
此外,Java本身负责遍历所有元素并进行比较,因此您不必这样做。看看其实现由以下类使用:AbstractMap
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;
}
toString
在比较时失败得很惨,尽管确实正确比较了内容。TreeMap
HashMap
equals
法典:
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}
只要覆盖映射中包含的每个键和值,那么检查映射是否相等就应该可靠。equals()
m1.equals(m2)
通过按照您的建议比较每个地图也可以获得相同的结果,但使用是一种更直观的方法。toString()
equals()
可能不是您的具体情况,但是如果您在映射中存储数组,可能会有点棘手,因为它们必须逐值比较,或者使用.有关此内容的更多详细信息,请参阅此处。Arrays.equals()