簡體   English   中英

哈希碼和等於

[英]Hashcode and equals

equalshashCode方法必須一致,這意味着當兩個對象根據equals方法相等時,它們的hashCode方法應該返回相同的哈希值。

如果我們不覆蓋hashCode()方法,Java將返回唯一的哈希代碼。

class HashValue {

    int x;

    public boolean equals(Object oo) {
        // if(oo instanceof Hashvalue) uncommenting ths gives error.dunno why?
        // :|
        HashValue hh = (HashValue) oo;

        if (this.x == hh.x)
            return true;
        else
            return false;
    }

    HashValue() {
        x = 11;
    }

}

class Hashing {
    public static void main(String args[]) {
        HashValue hv = new HashValue();
        HashValue hv2 = new HashValue();

        System.out.println(hv.hashCode());
        System.out.println(hv2.hashCode());

        if (hv.equals(hv2))
            System.out.println("EQUAL");
        else
            System.out.println("NOT EQUAL");
    }
}

為什么取消注釋該行會產生編譯錯誤?

如果對象具有不相等的哈希碼,為什么即使默認哈希碼變化,它們也顯示相等?

首先,在該行中,您需要將Hashvalue更改為HashValue ,因為您的類實際上稱為HashValue

然后,取消注釋該行為您提供:

public boolean equals(Object oo) {
    if(oo instanceof HashValue)
        HashValue hh = (HashValue)oo;

    if (this.x==hh.x) {
        return true;
    } else {
        return false;
    }
}

這有一些問題:

  1. 這不會編譯,因為當你最終使用它時, hh不在范圍內。

  2. 第一個if語句應該確保在比較兩個不是HashValues的東西(即拋出異常)時根本不運行該函數,或者它應該返回false因為HashValues永遠不會等於其他類型的對象。 我通常更喜歡返回false來拋出異常。

  3. 第二個if語句是多余的,因為您只是返回條件評估的內容。

像這樣重寫你的方法:

public boolean equals(Object oo) {
    if(!(oo instanceof Hashvalue)) {
        return false;
    }

    HashValue hh = (HashValue)oo;
    return (this.x == hh.x);
}

這也不太對勁。 為了確保所有相等的對象具有相同的哈希代碼,你必須覆蓋hashCode()HashValue必須確保它不辜負保證。 在這里,你可以添加這個:

// inside HashValue
int hashCode() {
    return x;
}

實現很簡單,因為你的對象只是一個int的包裝器。 隨着對象越來越復雜,你需要更加思考。

平等僅由方法equals()決定。 方法hashCode()用於其他情況,例如Map或Set。 在實際調用equals(效率)之前,它有點像先決條件或提示。 因此假設如果2個對象相等(即equals()返回true),則它們的hashCodes()必須返回相同的值。

所以在你的代碼中,2個對象是相等的,只要你的overriden equals()返回true,無論hashCode()是什么。 在比較相等性時,根本不調用hashCode()。

這個問題有關於equals()和hashCode()之間關系的更深入的信息。

對於初學者,你需要在“Hashvalue”中大寫v

if(oo instanceof Hashvalue)

應該

if (oo instanceof HashValue)

HashValueHashvalue是兩個不同的標識符

if(oo instanceof HashValue)有效的,因為你的類名是HashValue而不是Hashvalue

編輯:

您的代碼不起作用,因為當您使用它時, hh不在范圍內。

這有效:

/* A program to check hashcode values for object
@Author Myth17
 */

class HashValue 
{

   int x;

   public boolean equals(Object oo)
  {
    HashValue hh=new HashValue();
    if(oo instanceof HashValue) 
       hh = (HashValue)oo;

    if(this.x==hh.x)
      return true;
    else
      return false;
  }

   HashValue()
  {
     x=11;
   }

  }

 class  Hashing
 {
     public static void main(String args[])
    {
       HashValue hv=new HashValue();
       HashValue hv2=new HashValue();

      System.out.println(hv.hashCode());
      System.out.println(hv2.hashCode());

      if(hv.equals(hv2))
        System.out.println("EQUAL");
      else
         System.out.println("NOT EQUAL");
    }
  }

正如其他人已經指出的那樣,方法“等於”而“hashCode”用於不同的目的。

one can infer that: hashCode方法的規范可以推斷出:

  • 當對它們調用hashCode方法時, 需要兩個相等的對象返回相同的整數結果
  • that unequal objects return distinct integer values 強烈不等對象返回不同的整數值

has proposed) satisfies criteria (a) hence you get the output as "EQUALS". 您的代碼(考慮到提出的更改)滿足標准(a),因此您將輸出視為“EQUALS”。

但是遵循(b)是一種很好的做法,因為當使用類的實例作為哈希表鍵時,這會帶來更好的性能。 當不相等的對象返回相同的hashCode並且如果將這樣的類用作散列表鍵時,則每個對象散列到同一個桶,並且散列表將退化為鏈接列表,從而導致性能降低。

在以下代碼中:

public boolean equals(Object oo) {
    if(oo instanceof Hashvalue) 
        HashValue hh = (HashValue) oo;

    if (this.x == hh.x)
        return true;
    else
        return false;
}

有幾個問題:1。編譯器無法識別Hashvalue。 它應該是“HashValue”2。一旦超出if-block,hh就超出了范圍。 因此,編譯器錯誤。

您可以將程序更改為以下程序,它將起作用:

 public boolean equals(Object oo) {
     if(!(oo instanceof Hashvalue)) 
         return false;

     HashValue hh = (HashValue) oo;
     if (this.x == hh.x)
        return true;
     else
        return false;
}

或者你可以使它更簡潔如下:

 public boolean equals(Object oo) {
     if(oo instanceof Hashvalue && this.x == ((HashValue) oo).x) 
         return true;
     return false;
}
int x;
public static void main(String args[]){
    E a = new E();
    System.out.println(a.hashcode());
    E b = new E();
    System.out.println(b.hashcode());
}

public int hashcode(){
    return x*17;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM