作為一個程序員,我們都知道Java 中有兩個非常重要的概念 ==和Hashcode,今天我們就來一起了解一下它們的作用與區(qū)別。
首先,==(雙等號)是用于判斷兩個對象的內(nèi)存地址是否相同。如果兩個對象的地址相同,那么它們就是同一個對象,也就是說,它們指向的是同一個內(nèi)存空間。但是,如果兩個對象的內(nèi)存地址不同,那么它們就不是同一個對象。因此,== 運算符只適用于判斷基本類型和對象的地址。
public static void main(String[] args) { String str1 = "hello"; String str2 = "hello"; String str3 = new String("hello"); System.out.println(str1 == str2); // true System.out.println(str1 == str3); // false }
通過上面這個例子可以看出,str1和str2都是指向同一個內(nèi)存空間,因為它們都是字符串常量,Java 在編譯時就會把它們放到常量池中,所以它們的內(nèi)存地址相同,返回 true。而 str3 是通過 new 關(guān)鍵字創(chuàng)建的一個新對象,所以它的內(nèi)存地址與 str1 不同,返回 false。
接下來介紹 Hashcode,每個 Java 對象都有一個 Hashcode 值,它是一個整數(shù),由 JVM 根據(jù)該對象的內(nèi)存地址計算得出。當我們使用一些容器類,如 HashMap、HashSet 等時,我們需要讓對象具有可比較性。在這種情況下,我們就可以復寫 Hashcode 和 equals 方法。如果兩個對象根據(jù) equals 方法比較相等,那么它們的 Hashcode 值也應該相同。
public class User { private String name; private int age; public User(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 == null || getClass() != obj.getClass()) { return false; } User user = (User) obj; if (age != user.age) { return false; } return Objects.equals(name, user.name); } }
在上面這個例子中,我們重寫了 User 類的 Hashcode 和 equals 方法。在 Hashcode 方法中,我們需要注意,同一對象每次調(diào)用 Hashcode 方法返回的值必須相同。所以,我們使用了一種常用的計算 Hashcode 的方法:
- 初始化一個 int 類型的變量 result = 17;
- 把 31 乘以 result,并加上 name 的哈希值;
- 再把 31 乘以 result,加上 age 的哈希值。
這樣計算得到的 Hashcode 值,足夠分布均勻,在相等的時候可以最大程度地減少沖突!
在重寫 equals 方法時,我們首先判斷兩個對象是否是同一實例,如果是直接返回 true。然后,我們需要逐個比較對象的屬性,如果屬性都相等,那么它們就相等。在比較屬性時,我們要注意做 null 判斷,所以使用了 Objects.equals() 方法。
可以看出,在 Java 編程過程中,== 和 Hashcode 是兩個非常重要的概念。理解它們的作用和區(qū)別,對于我們開發(fā)高質(zhì)量的程序有著至關(guān)重要的作用。