簡體   English   中英

刪除重復項而不覆蓋哈希方法

[英]Removing duplicates without overriding hash method

我有一個List,其中包含一個對象列表,我想從這個列表中刪除所有在兩個屬性中具有相同值的元素。 我曾做過這樣的事情:

List<Class1> myList;
....
Set<Class1> mySet = new HashSet<Class1>();
mySet.addAll(myList);

並重寫Class1中的哈希方法,因此它返回一個僅取決於我想要考慮的屬性的數字。

問題是我需要在應用程序的另一部分進行不同的過濾,所以我不能以這種方式覆蓋哈希方法(我需要兩種不同的哈希方法)。

在不重寫哈希方法的情況下進行此過濾的最有效方法是什么?

謝謝

Class1重寫hashCodeequals (只是為了做到這一點)是有問題的。 你最終會對你的班級有一個不自然的平等定義,這可能會成為班級其他當前和未來用途的其他用途。

查看Comparator接口並編寫Comparator<Class1>實現,以根據您的標准比較Class1的實例; 例如,基於這兩個屬性。 然后使用TreeSet(Comparator)構造函數實例化TreeSet<Class >`以進行重復檢測。

編輯

將這種方法與@Tom Hawtin的方法進行比較:

  • 這兩種方法總體上使用大致相當的空間。 treeset的內部節點大致平衡了hashset的數組和支持自定義equals / hash方法的包裝器。

  • 對於樹集方法,包裝器+哈希集方法在時間上是O(N) (假設是良好的哈希)而不是O(NlogN) 因此,如果輸入列表可能很大,那就是要走的路。

  • 樹形集方法在需要編寫的代碼行方面獲勝。

讓你的Class1實現Comparable 然后在您的示例中使用TreeSet (即使用addAll方法)。

作為Roman所說的替代方法,您可以查看有關使用Predicates進行過濾的SO問題 無論如何,如果你使用谷歌收藏,這可能是一個不錯的選擇。

我建議為Class1的部分概念引入一個類,你想在這個上下文中考慮重要。 然后使用HashSetHashMap

有時程序員會嘗試使用語言的所有優秀功能而使事情過於復雜,而這個問題的答案就是一個例子。 覆蓋課堂上的任何內容都是過度的。 你需要的是這個:

class MyClass {
  Object attr1;
  Object attr2;
}

List<Class1> list;
Set<Class1> set=....
Set<MyClass> tempset = new HashSet<MyClass>;

for (Class1 c:list) {
  MyClass myc = new MyClass();
  myc.attr1 = c.attr1;
  myc.attr2 = c.attr2;

  if (!tempset.contains(myc)) {
    tempset.add(myc);
    set.add(c);
  }
}

隨意修復輕微的irregulairites。 根據屬性的相等性意味着一些問題(如果屬性是原始的,則會有明顯的變化)。 有時我們需要編寫代碼,而不僅僅是使用內置庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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