一、HashMap簡介
在Java中,HashMap是最常用的一種數據結構之一。它能夠在O(1)的時間複雜度內進行插入、查找、刪除,因此在數據量較大的情況下,使用HashMap能夠有效地提高代碼的性能。HashMap是基於哈希表實現的,它通過鍵值對的方式進行存儲,也就是說,我們需要指定一個鍵(key)和它所對應的值(value)。在HashMap中,key是唯一的,而value可以有重複。
二、HashMap的Key值
在使用HashMap時,我們必須要了解如何處理Key值,因為Key是HashMap中最重要的部分。通常我們會在HashMap中使用自定義類型的Key,這時我們需要保證Key是唯一的。在Java中,我們可以使用equals方法來判斷兩個對象是否相等。因此,我們需要重寫自定義Key的equals和hashCode方法,以保證 HashMap 能夠正確地處理Key。
在實際開發中,有一些常見的問題需要考慮。例如,String、Integer、Long等包裝類已經重寫了equals和hashCode方法,因此我們可以直接使用它們作為Key。但是,如果我們使用自定義類型的對象作為Key時,我們需要注意一些問題:
三、自定義類型作為Key
1、使用不可變類型作為Key
在使用自定義類型作為Key時,要注意Key必須是不可變類型。不可變對象的值在對象創建之後就不能再被改變,這可以保證hashCode不會發生改變。如果我們使用可變的對象作為Key,那麼在對象的值改變之後,hashCode也會改變,這樣就會導致HashMap中的元素無法被準確地找到。
示例代碼:
public class Person { private final String name; private final int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public int hashCode() { return Objects.hash(name, age); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof Person)) { return false; } Person person = (Person) obj; return age == person.age && Objects.equals(name, person.name); } }
2、hashCode的正確性
在我們重寫hashCode方法的時候,需要注意一些細節。hashCode必須滿足以下條件:
- 在Java應用程序當前運行期間,如果在對象上多次調用 hashCode 方法,它必須始終返回相同的整數。
- 如果兩個對象根據 equals(Object) 方法是相等的,則調用這些對象中的每個對象的 hashCode 方法必須產生相同的整數結果。
- 如果兩個對象根據 equals(Object) 方法不相等,則對這些對象中的任一對象上調用 hashCode 方法不要求產生不同的整數結果。但是,為每個不相等的對象生成一個惟一的整數結果可以提高哈希表的性能。
示例代碼:
public class Person { private final String name; private final int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public int hashCode() { int result = 17; result = 31 * result + name.hashCode(); result = 31 * result + age; return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof Person)) { return false; } Person person = (Person) obj; return age == person.age && Objects.equals(name, person.name); } }
3、equals方法的正確性
equals方法是判斷兩個對象是否相等的方法。在重寫equals方法時,我們需要保證滿足以下條件:
- 自反性:對於任何非空引用x,x.equals(x)必須返回true。
- 對稱性:對於任何非空引用x和y,如果x.equals(y)返回true,那麼y.equals(x)必須返回true。
- 傳遞性:對於任何非空引用x、y、z,如果x.equals(y)返回true,y.equals(z)返回true,那麼x.equals(z)必須返回true。
- 一致性:如果兩個對象是相等的,那麼在它們的整個生命周期中調用equals方法必須返回true。
- 非空性:對於任何非空引用x,x.equals(null)必須返回false。
示例代碼:
public class Person { private final String name; private final int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public int hashCode() { int result = 17; result = 31 * result + name.hashCode(); result = 31 * result + age; return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof Person)) { return false; } Person person = (Person) obj; return age == person.age && Objects.equals(name, person.name); } }
四、小結
在使用HashMap時,Key值的正確處理對於正確性和性能具有很大的影響。我們需要確保Key是唯一的,而且不能改變。為了確保HashMap能夠正確地處理Key,我們需要重寫equals和hashCode方法,並且保證它們滿足條件。只有這樣,我們才能使用自定義類型作為Key,從而優化代碼的性能。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/244933.html