2017-04-13 60 views
0
public Class myClass{ 
private final int[][] board; 
} 

有重複的哈希碼對不同的對象

LinkedHashMap<Integer,Object> myMap 

其中Integer是一個哈希碼我創建使用Arrays.deepHashCode

public int hashCode() { 
     int hash = 5; 
     hash = 89 * hash + Arrays.deepHashCode(this.board); 
     return hash; 
    } 

public boolean equals(Object anObject) { 
     if (anObject == null) return false; 
     if (anObject == this) return true; 
     if (!(anObject instanceof myClass))return false; 

     Puzzle anotherClass = (myClass)anObject; 
     return Arrays.deepEquals(this.board,anotherClass.board); 
    } 

我得到新的對象,我需要將它們添加到myMap只有當它們不存在。 我試圖用myMap.containsKey(hashcode)檢查哈希碼,顯然我得到了不同對象的重複哈希碼。

我試圖檢查進一步的細節,當我從myMap.containsKey(hashcode)成爲true,但然後我不能將它們添加到myMap,因爲它們具有相同的鍵!

是否有任何解決此問題的方法,因爲使用ArrayList和檢查是非常緩慢的,我有大量的迭代。

+4

你不應該使用'Integer'作爲地圖的關鍵;你應該使用'Board'對象作爲鍵,這應該是'Board.hashCode()'的實現。 –

+4

你的董事會有多大?順便說一句,請不要命名類「對象」。 – kennytm

+0

爲什麼你還需要使用Map?如果你只想擁有一個不允許重複輸入的「列表」,那麼使用一個簡單的Set即可。 –

回答

-1

我暫時離開這個後代爲後代,但基本上其他海報是正確的,你應該使用HashSet。請參閱下面的評論,瞭解如何執行自己的集合類可能會非常棘手。你有正確的想法,但細節讓你感到沮喪。


錯誤,將無法正常工作:

我的肢體這裏走出去,猜你沒有實現equals()爲你的類。

如果您實施hashcode()您還必須實施equals(),否則無效。 (或者至少有很多東西不能很好地工作。)

+2

問題不在於此。 OP正在使用hashCode()直接作爲密鑰... – kennytm

+0

基本上HashSet是如何工作的,對吧?這應該是可能的,即使這不是一個好主意。我的另一個擔憂是,如果他改變了這個數組,他將得到一個不同的哈希碼,這真的會導致問題。 – markspace

+2

@markspace no。 HashSet使用對象本身作爲其內部映射的關鍵字。不是對象的hashCode。如果它使用了hashCode,那麼該集合會拒絕兩個具有相同hashCode但不相等的對象。 –

1

看起來你錯過了這裏的一些關鍵點。

第一個,您不需要在您的Map中使用散列碼值作爲鍵。相反,您必須使用實現散列碼的對象。

第二個,作爲合同的一部分,您必須實現Object類的hashcode()和equals()方法,以確保那些依賴於這些類的類(如HashMap,HashSet等)方法正常工作

第三,你必須做一些研究如何編寫一個好的散列函數,以儘量減少兩個對象具有相同散列碼值的可能性。 看在下面的線程

What is a best practice of writing hash function in java?

How to write hashCode method for a particular class?