1. 程式人生 > >Java中的Object類 (上篇)

Java中的Object類 (上篇)

 

 要麼讀書,要麼旅行,身體和心靈總有一個要在路上。——羅馬假日

 

咱今天學習的是Java的Object類,首先先看程式碼,類裡面有哪些方法。

咱今天學習兩個方法,分別是hashCode,equals。

 Object中的hashCode方法就是根據一定的規則與物件相關的資訊對映成一個數值,這個數值稱為雜湊值。

  public native int hashCode();

這時有個關鍵字native,Java平臺有個使用者和本地C程式碼進行互動操作的API,稱為Java Native Interface(簡稱為JNI)。

 Object中的equals方法是用來比較兩個物件是否相等的,即object1.equals(object2)為true,則表示object1和object2實際上是引用的同一個物件,但是我們大部分時候進行的是兩個物件值的比較,而非地址的比較,所以這個時候,Object的equals方法就不行了。

這時候有的小哥哥要說不對啊,我們平常也使用了String,Integer,Long型別也進行了equals比較啊,他是比較的值,而非地址,你這不會瞎扯淡吧。

不慌不慌,咱慢慢看,先上程式碼看一下,如果是String型別,使用equals是不是比較的值。

public class Test {
  public static void main(String[] args){
     String str1="abc";
     String str2="abc";
     System.out.println(str1.equals(str2));
  }
}

 咱執行下程式碼,會發現的確列印的true,說明是比較了str1和str2的值。因為在上篇我們說過了str是一個常量,每次的string型別的資料的地址都是不一樣的,不明白的可以移步上篇,https://blog.csdn.net/qq_33774822/article/details/82757055,那不打臉了嗎。

開玩笑,怎麼可能打臉呢,那咱來看一下這個為什麼呢

原來啊,是String類裡面重寫了equals方法,980行到994行之間就是對兩個string型別資料的比較。感謝Java粑粑,這時候是不是應該響起一首歌,你還要我怎樣,要怎樣。


 但是這是常見的型別,那比如我們自定義了一個物件型別,要比較兩個物件是否相等,那該怎麼做呢,應該是重寫equals方法,這裡說明一下,如果兩個物件通過equals來比較返回的是true,就說明這兩個值相等,那麼這兩個物件的hashCode也應該返回相同的值。這是hashCode的常規規定,咱必須得遵守呢。

hashCode還有一個規定就是在程式執行時,同一物件多次呼叫hashCode方法應該返回相同的值。

基於以上的兩個規定,我們自定義了一個Person類,裡面有id,name,還重寫了equals和hashCode方法。

上程式碼咯:

public class Person {

  private String id;
  private String name;

  public String getId() {
    return id;
  }

  public void setId(String id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  @Override
  public boolean equals(Object o) {
    if (o == this) {
      return true;
    }
    if (!(o instanceof Person)) {
      return false;
    }
    Person person = (Person) o;
    return person.getId().equals(id) && person.getName().equals(name);
  }

  @Override
  public int hashCode() {
    int result = 17;
    result = result * 31 + name.hashCode() + id.hashCode();
    return result;
  }
}

這裡要重點說明一下重寫hashCode的時候,用的是31來乘以result,這是為了讓產生的hashCode唯一。

主要的原因有兩個:

1.更少的乘積結果衝突。31是質數中不大不小的存在,如果使用如3這樣比較小的質數,那麼得出的乘積會在一個很小的範圍內,很容易造成雜湊值衝突。如果選擇100以上的質數,得到的雜湊值會超過int的最大範圍。所以這兩種都不適合。

2.31可以被JVM優化,31=2<<5-1,JVM可以自動識別為位運算。