[英]How to check equality between 2 HashMap<Number, String>?
I would like to check equality between 2 HashMap<Number,String>
. 我想检查2
HashMap<Number,String>
之间的相等性。 My idea is converting each Number into BigDecimal with new BigDecimal(number.toString())
and then check equality with compareTo() == 0
instead of the basic equals
that is used when comparing 2 Maps. 我的想法是使用
new BigDecimal(number.toString())
将每个Number转换为BigDecimal,然后使用compareTo() == 0
而不是比较2个Map时使用的基本equals
来检查相等性。
Who has a good implementation of this, or even better : a better idea ? 谁能很好地实现这一目标,甚至更好:更好的主意?
This seems a lot like an XY problem ; 这看起来很像XY问题 ; as pointed out in the comments it doesn't make a lot of sense to be comparing arbitrary
Number
objects; 如评论中所指出的,比较任意
Number
对象没有多大意义; why not just make your maps Map<BigDecimal, String>
and just always use BigDecimal
directly ( normalized with stripTrailingZeros()
if necessary)? 为什么不只让您的地图
Map<BigDecimal, String>
并始终直接直接使用BigDecimal
(必要时使用stripTrailingZeros()
标准化 )? Then you can just use standard Map
equality. 然后,您可以使用标准
Map
相等性。 Consider stepping back and asking whether you really need the behavior you're describing in the first place. 考虑退后一步,询问您是否真的需要您首先描述的行为。
Notably, Number
doesn't implement Comparable
, which should be a pretty clear hint that you shouldn't try to compare arbitrary Number
instances. 值得注意的是,
Number
没有实现Comparable
,这应该是一个很明确的提示,即您不应该尝试比较任意Number
实例。
If that isn't an option for some reason, here's a reasonable implementation of the behavior you're describing. 如果由于某种原因这不是一个选择,则这是您描述的行为的合理实现。
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;
}
Alternatively just copy both maps to TreeMap<BigDecimal, V>
and call .equals()
, but that requires copying both maps, whereas numberMapEquality()
only needs to copy one, avoids any copying if they're not the same size, and detects key collisions. 另外,也可以将两个地图都复制到
TreeMap<BigDecimal, V>
并调用.equals()
,但这需要复制两个地图,而numberMapEquality()
只需要复制一个,避免大小不相同的任何复制,并检测按键碰撞。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.