簡體   English   中英

如何檢查2 HashMap之間的相等性 <Number, String> ?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM