2013-08-03 27 views
1

假設我想將一個鍵和它的值放入一個Map中。爲什麼Java使用'equals'而不是'=='來檢查Map中對象的存在?

我相信這就是Java做什麼:

  1. 拿到鑰匙的散列碼,並檢查是否有具有相同散列碼地圖的關鍵。

  2. 如果沒有具有相同哈希碼的密鑰,則可以將該密鑰放入地圖中。

  3. 如果存在具有相同哈希碼的密鑰,則使用等於來確定該密鑰是否可以放入Map中。

我的問題是,爲什麼在這個過程中不使用==代替equals

+0

讓程序員定義'equals'可以自由決定什麼東西確切定義一個對象是「相等的」。對於兩個對象是平等的,所有的成員都需要完全一樣嗎?如果一個對象具有'timeCreated'變量,但其他所有內容都是相同的呢?讓程序員控制並定義是什麼使對象相等或不相等一個非常基本的例子:「Hello」和「Hello」可以是相同的或不同的,具體取決於解釋。另外,哈希可能會發生碰撞,儘管可能性非常小。 – BLaZuRE

+5

BTW IdentityHashMap使用'=='而不是Map。 –

回答

11

做你的建議會破壞串聯的整個概念equals/hashCodeequalshashCode都將變得無用,甚至不應該存在。

Java允許程序員爲他的類定義相等集;如果他不想這樣做,他可以簡單地選擇重寫equalshashCode —,並最終得出您提出的確切語義。

舉一個具體的例子,你的建議下,這將在地圖上創建兩個單獨的條目:

Map<Integer, String> map = new HashMap<>(); 
map.put(10_000, "a"); 
map.put(10_000, "a"); 

這是因爲字面10_000每次將autoboxed成Integer一個新的實例,該實例在你的語義下,是兩個獨立的鍵。然後,聲明

System.out.println(map.get(10_000)); 

將打印null,自然是因爲你使用的是第三鍵搞定。事實上,通過密鑰來檢索任何地圖值是不可能的。

+0

我現在明白了。感謝你的回答。 –

2

因爲「==」是用來在使用Java集合JFrame的是重寫equals方法來比較兩個對象和.equals()的content.One重要規則的參考,同時也.hashCode()所以,如果你有2個對象與相同的內容被映射到相同的密鑰(哈希碼)。 如果你不覆蓋.enquals,那麼調用的方法將會比Object類中的引用更加「==」。當你覆蓋.hashCode()時,一個重要的細節是使用final字段。

2

在java ==用於檢查參考等號,而equals()和hashCode()一起作爲'single concept'用於對象相等。
如果您需要一個適用於==的地圖,請使用IdentityHashMap

+0

用於IdentityHashMap的+1 –

2

鍵是對象類型,所有的類都是從Object類派生出來的。如果你正在使用你寫的類的關鍵字,並且你沒有在你的類中重寫equals方法,會發生什麼?答案如下:

無論您的類的兩個對象是否具有完全相同的屬性值,但仍等於的結果將爲false。只是因爲默認等於推測會檢查兩個對象是否指向相同的內存位置。這正是==比較所做的。

現在來到equals和not ==的哈希映射使用。這是因爲當你嘗試在地圖中放置一個鍵時,JVM會嘗試檢查兩個對象是否相等。 JVM檢查這種相等性的唯一智能是使用equals方法。並且使用它的默認實現,它將執行==比較將會執行的操作。但正如我上面提到的,如果兩個對象具有相同的屬性,那麼它們實際上是相等的。但令人遺憾的是,==比較不能進行屬性比較,並且具有真正的價值。因此,重寫equals方法或使用equals方法在邏輯上非常重要,同時將值存儲在Map中。

4

==從面向對象的意義上講,沒有多大意義。

new Integer(3)new Integer(3)new Integer(2+1)應該全部被認爲是相等的。其他一切都很令人困惑,這就是equals所描述的。如果沒有這個,當你沒有對原始鍵的引用時,就不可能從HashMap()中提取任何東西。當基於來自數據庫的數據將東西放入HashMap中時,也不可能使用來自用戶的輸入在HashMap中查找某些東西。

如果你身邊==equalshashCode它是==應該真的是找問題,「等於」和參照完整性應該有一些模糊的句柄,沒有人真正知道,因爲你永遠不會使用它。順便說一句,這正是其他語言例如斯卡拉呢。

相關問題