2012-07-22 276 views
27

好了,在Java 7中,我們有Objects.hash()VS Objects.hashCode(),澄清需要

o.hashCode(); 
    Objects.hashCode(o); 

    Objects.hash(o); 

第2大致與零點檢查相同,但什麼是最後一個?

當提供單個對象引用時,返回的值確實不等於該對象引用的哈希碼。

這是爲什麼?我的意思是,我們不需要3種方法來做同樣的事情,我明白......但我們爲什麼需要Objects.hash()?你什麼時候選擇使用一個vs另一個?

回答

47

請參閱hashCodehash的文檔。 hash需要Object...,而hashCode需要Object。給出的例子是:

@Override public int hashCode() { 
    return Objects.hash(x, y, z); 
} 
  • Objects.hash(Object... values)應在情況下,當你想要的對象序列,例如的散列使用當定義你自己的hashCode方法並且需要一個簡單編碼的散列值來組成你的對象的身份。
  • Objects.hashCode(Object o)應該在需要單個對象的散列時使用,如果對象爲空則不會拋出。
  • Object::hashCode()應該在需要單個對象的散列時使用,並且如果對象爲空則會引發異常。

請注意,hash(o)hashCode(o)不一定會返回相同的東西!如果你正在爲一個對象做這件事,你應該使用hashCode

+0

在什麼情況下'散列(o)'和'hashCode(o)'不會返回相同的值? ''hash()'state'的文檔警告:當提供單個對象引用時,返回的值不等於該對象引用的哈希代碼,但我仍在挖掘以找出原因。 – 2017-08-24 13:25:57

7

Object的默認hashCode()返回該對象的內存地址。所以,如果你有下面的類:

class Car { 
    String make; 
    String model; 
    int year; 

    public Car(String make, String model, int year) { 
     this.make = make; 
     this.model = model; 
     this.year = year; 
    } 
} 

再創建兩個對象:

Car car1 = new Car("Toyota", "Corolla", 2010); 
Car car2 = new Car("Toyota", "Corolla", 2010); 

car1.hashCode()將從car2.hashCode()不同,因爲每個對象都會有一個不同的內存地址。

如果您想讓car1和car2返回相同的哈希碼,該怎麼辦?在這種情況下,你應該覆蓋默認的對象的hashCode()方法爲汽車類,如下所示:

@Override 
public int hashCode() { 
    Object[] x = {model, make, Integer.valueOf(year)}; 
    int hashArray = Arrays.hashCode(x); 
    return hashArray; 
} 

這將使car1.hashCode()等於car2.hashCode(),因爲String.hashCode()根據字符串內容計算hashCode,Integer.hashCode()將返回整數值本身。

在Java 7中,您可以使用Objects.hash(Object ... values)。因此,我們的新車hashCode()方法將如下所示:

@Override 
public int hashCode() { 
    return Objects.hash(model, make, year); 
} 

Objects.hash(對象...值)將調用Arrays.hashCode你。

最後,Objects.hashCode(Object o)將執行空檢查。如果對象爲null,它將返回0。否則,它會調用對象的hashCode()方法。

+0

大約20年來,默認的'hashCode()'沒有返回內存地址。它不能真的。 GC移動物體。所謂的內存地址就是不可移動的句柄。 – EJP 2018-02-19 05:58:31

+0

基於Java文檔https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode hashCode「通常通過將對象的內部地址轉換爲一個整數,但這種實現技術不是Java™編程語言所必需的。「 – ezzadeen 2018-02-25 00:39:01