什麼是哈希碼(HashCode)

哈希碼

編輯本段什麼是哈希碼(HashCode)

  在Java中,哈希碼代表對象的特徵。
  例如對象 String str1 = “aa”, str1.hashCode= 3104
  String str2 = “bb”, str2.hashCode= 3106
  String str3 = “aa”, str3.hashCode= 3104
  根據HashCode由此可得出str1!=str2,str1==str3
  哈希碼產生的依據:哈希碼並不是完全唯一的,它是一種算法,讓同一個類的對象按照自己不同的特徵儘量的有不同的哈希碼,但不表示不同的對象哈希碼完全不同。也有相同的情況,看程序員如何寫哈希碼的算法。
  下面給出幾個常用的哈希碼的算法。
  1:Object類的hashCode.返回對象的內存地址經過處理後的結構,由於每個對象的內存地址都不一樣,所以哈希碼也不一樣。
  2:String類的hashCode.根據String類包含的字符串的內容,根據一種特殊算法返回哈希碼,只要字符串內容相同,返回的哈希碼也相同。
  3:Integer類,返回的哈希碼就是Integer對象裏所包含的那個整數的數值,例如Integer i1=new Integer(100),i1.hashCode的值就是100 。由此可見,2個一樣大小的Integer對象,返回的哈希碼也一樣。

編輯本段equals方法在hibernate中的應用。

  equals方法是默認的判斷2個對象是否相等的方法,在Object類裏有實現,判斷的是2個對象的內存地址。在hibernate中,不允許存在同類對象中有2個一樣的實例。hibernate通過equals方法做判斷。如:
  User u1 = new User(“張三”);
  User u2 = new User(“李四”);
  User u3 = new User(“張三”);
  按照項目需求,用戶只要名字相同,就表示同一個用戶,所以我們認爲,u1和u3是同一個人,同一個對象。但是因爲u1,u2,u3三者的內存地址都各不相同,所以hibernate會認爲這是3個不同的對象。這與我們假設的出了矛盾。 因此,我們將覆蓋User的equals方法。
  public class User{
  private String userName;
  ….//get ,set方法省
  //覆蓋Object裏的equals方法
  public boolean equals(Object arg0){
  if (!(arg0 instanceof User)){
  return false;
  }
  User user = (User)arg0;
  //如果名字相同,則表示屬於同一個對象。
  if(user.getName().equals(this.getName)){
  return true;
  }else{
  return false; }
  }
  這樣hibernate在插入數據的時候,如果傳過來一個叫”張三”的用戶,hibernate會先判斷有沒有叫“張三”的用戶,如果沒有,就允許插入,如果有,就不允許插入。這樣做可以保證數據的高度一致性,不同的項目有不同的需求,所以要根據自己的需求來覆蓋equlas方法。

編輯本段爲什麼不按主鍵來判斷

  因爲主鍵是在插入數據進數據庫之後才產生的,在一個對象還沒有被持久化的時候,它是沒有主鍵的,所以hibernate無法根據主鍵判斷它是否有相同數據。

編輯本段equlas和HashCode的關係

  在hibernate中,它認爲2個對象只要equlas返回true,那麼hashCode一定相等。 但是實際情況呢?
  User u1 = new User(“張三”);
  User u2 = new User(“張三”);
  由於我們重寫了User的equlas方法,所以 u1.equlas(u2);返回true 但是,User並沒有重寫hashCode方法,它用的是Object類的hashCode方法,所以 u1.hashCode = 31050006 u2.hashCode = 31587890 兩者的hashCode並不相等。違背了hibernate的原則 由此hibernate會產生錯誤判斷,又以爲它們不是同一個對象,因此我們還得重寫User 的hashCode方法。如何重寫hashCode方法呢?

編輯本段HashCode的重寫

  如第2節所講,哈希碼要完成這麼一件事,首先要保證如果equlas出來的結果相等,那麼hashCode也相等。像上面的u1和u2,由於名字都是“張三”,所以應該返回相同的hashCode。所以我們可以想一個辦法。讓User的哈希碼返回User裏面name字段的哈希碼,這樣就保證,名字相同的人,不但equlas方法相同,而且hashCode相等。 那麼User類就變成
  public class User{
  private String userName;
  //覆蓋Object裏的equals方法
  public boolean equals(Object arg0){
  if(!(arg0 instanceof User)){
  return false;
  }
  User user = (User)arg0;
  //如果名字相同,則表示屬於同一個對象。
  if (user.getName().equals(this.getName)){
  return true;
  }else{
  return false;
  }
  }
  //覆蓋Object裏的hashCode方法
  public int hashCode() {
  return name.hashCode();//返回名字的哈希碼。
  }
  }
  這樣可以保證hibernate根據我們自己的需求來判斷重複對象
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章