2013-04-10 86 views
1

我正在尋找一個Map實現,它可以根據鍵和比較器進行排序。Sorted Map with not defined defined Comparators

我知道TreeMap是要走的路,但我有一個很大的問題:比較器沒有很好的定義(我知道是一個錯誤,但我目前無法修復),它甚至返回0對於不相等的鍵(按照equals()方法)。

樹形圖實現假定對象是相等的(且因此覆蓋值)如果比較器返回0並沒有考慮哈希碼或對象的equals方法考慮。這是記錄在案,並在大多數情況下所需的行爲。您可以檢查的實施是基於比較通過查看TreeMap.put()方法,它包含以下snipset:

 do { 
      parent = t; 
      cmp = cpr.compare(key, t.key); 
      if (cmp < 0) 
       t = t.left; 
      else if (cmp > 0) 
       t = t.right; 
      else 
       return t.setValue(value); 
     } while (t != null); 

此代碼遍歷樹,如果它發現樹中的一個節點,其(使用比較器cpr)與應插入的值(key)相同時,該值將被覆蓋。

但是:我在尋找的Map接口的實現是基於一個比較器進行排序,但不使用它用於檢測相等。

+0

你在地圖上放置了一些你的類或java類嗎? – 2013-04-10 07:53:11

+0

對於鍵和值:我的類 – theomega 2013-04-10 07:54:58

+0

就我所知,map是由Sets實現的,並且object是否在set中,由對象本身的hashCode()確定,而不是由比較器的equals確定,所以爲什麼TreeMap是不工作? – 2013-04-10 08:01:46

回答

2

我懷疑你會找到一個地圖,做那個,因爲它違背了Comparator接口的建議。

由比較器C上的一組元件S的所施加的排序所述 爲符合等於當且僅當c.compare(E1,E2)== 0具有 相同的布爾值如e1.equals(E2),用於S.

注意每e1和e2應該使用能夠 比較器強加的排序不一致與equals訂購排序設置 (或有序映射)時行使。假設一個排序集合(或有序映射)以顯式 比較器c用於與來自一組S.繪製的元素(或多個密鑰)如果 被C S上施加的順序與equals,排序 組不一致(或有序地圖)會奇怪地表現「。「特別是排序的 集合(或排序映射)將違反集合的一般合同(或 映射),它是根據等式定義的。

您可以隨時與自己的比較裝點比較像這樣new MyComparator(faultyComparator);

當你deletegate將故障比較呼叫,檢查它的返回值。如果它是0,請確保對象的equals()合同一致。如果他們不這樣做,請糾正退貨價值。更好的解決方案是正確重寫比較器並使用TreeMap(如果該選項打開)。

+0

包裝比較器的解決方案是好的,我希望不要被迫使用它... – theomega 2013-04-10 08:17:22

+1

困難的部分與包裝比較器確保所有配對都是一致的,即使當原始比較器認爲它們相等時也是如此。你不能簡單地讓它總是返回-1或+1,因爲這會破壞TreeMap。 – 2013-04-10 08:19:46

+1

不幸的是,如果你不能修改「比較器」本身,你的選擇是有限的。 @IanRoberts所暗指的也是正確的。我的裝飾解決方案假定您有足夠的信息來對a> b作出明智的決定,反之亦然。任意返回-1/+1將無法正常工作。 – 2013-04-10 08:23:22

0

TreeMap在你的情況下應該沒問題。但是,這聽起來像你沒有使用Strings或Wrapper類對象作爲鍵。如果您使用自己的類對象作爲鍵,則必須實現hashcode()和equals()方法。

+0

我的等號和哈希碼的實現是正確的,問題是不正確的比較器,我(如上所述) 不能變。 – theomega 2013-04-10 08:06:55

+0

爲什麼你需要擔心比較器?您是否在TreeMap中使用了自己的程序中的任何Comparator? – IndoKnight 2013-04-10 08:08:53

+0

是的,我正在使用不正確實施的自定義比較器。 – theomega 2013-04-10 08:15:56

0

只需實現一個從不返回0並使用常規TreeMap的Comparator。

0

這將是更多的看家,但它聽起來像你需要某種形式的兩級結構,TreeMap<K, LinkedHashMap<K, V>>其中外部地圖是基於你的「錯誤的」比較,它的值是正常的等值感知的地圖(它們的鍵將根據比較器而全部相等,但根據hashCode和equals而不同)。