[英]How to check equality between 2 HashMap<Number, String>?
我想检查2 HashMap<Number,String>
之间的相等性。 我的想法是使用new BigDecimal(number.toString())
将每个Number转换为BigDecimal,然后使用compareTo() == 0
而不是比较2个Map时使用的基本equals
来检查相等性。
谁能很好地实现这一目标,甚至更好:更好的主意?
这看起来很像XY问题 ; 如评论中所指出的,比较任意Number
对象没有多大意义; 为什么不只让您的地图Map<BigDecimal, String>
并始终直接直接使用BigDecimal
(必要时使用stripTrailingZeros()
标准化 )? 然后,您可以使用标准Map
相等性。 考虑退后一步,询问您是否真的需要您首先描述的行为。
值得注意的是, Number
没有实现Comparable
,这应该是一个很明确的提示,即您不应该尝试比较任意Number
实例。
如果由于某种原因这不是一个选择,则这是您描述的行为的合理实现。
private static BigDecimal toBigDecimal(Number n) {
return n instanceof BigDecimal ? (BigDecimal)n : new BigDecimal(n.toString());
}
public static <V> boolean numberMapEquality(
Map<Number, ? extends V> a, Map<Number, ? extends V> b) {
if (a == b) return true;
if (a.size() != b.size()) return false;
// TreeMap uses .compareTo(), not .equals()
TreeMap<BigDecimal, V> bdMap = new TreeMap<>();
for (Entry<Number, ? extends V> e : a.entrySet()) {
bdMap.put(toBigDecimal(e.getKey()), e.getValue());
}
if (bdMap.size() != a.size()) {
// comment out if you don't care about this edge-case - but you should
throw new IllegalArgumentException(
"Multiple keys in 'a' normalize to the same value; " +
"equality comparison is unsafe.");
}
// Taken from AbstractMap.equals()
for (Entry<Number, ? extends V> e : b.entrySet()) {
BigDecimal bdKey = toBigDecimal(e.getKey());
V value = e.getValue();
if (value == null) {
if (!(bdMap.get(bdKey)==null && bdMap.containsKey(bdKey)))
return false;
} else {
if (!value.equals(bdMap.get(bdKey)))
return false;
}
}
return true;
}
另外,也可以将两个地图都复制到TreeMap<BigDecimal, V>
并调用.equals()
,但这需要复制两个地图,而numberMapEquality()
只需要复制一个,避免大小不相同的任何复制,并检测按键碰撞。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.