1.hashCodeメソッドを導入します
-
hashCode()
の役割は、ハッシュコード(ハッシュコードとも呼ばれます)を取得することです。実際には、int整数を返します。このハッシュコードの役割は、ハッシュテーブル内のオブジェクトのインデックス位置を決定することです。 -
hashCode()
JDKのObject.javaで定義されています。これは、JavaのすべてのクラスにhashCode()
関数。 -
ハッシュテーブルにはキーと値のペアが格納され、その特徴は、対応する「値」を「キー」に従ってすばやく取得できることです。ここでハッシュコードが使用されます!(目的のオブジェクトをすばやく見つけることができます)。
2.なぜhashCodeメソッドが必要なのですか?
プログラムを作成する過程で、2つのオブジェクトが同じであるかどうかを判断することは非常に一般的であり、しばしば直面する問題です。このhashCode()
メソッドは、2つのオブジェクトを比較する速度を向上させるために使用されます。
例として「HashSetが重複をチェックする方法」を取り上げて、hashCodeがある理由を説明しましょう。
-
オブジェクトを追加
HashSet
する、HashSetは最初hashcode
にオブジェクトの値を計算して、オブジェクトが追加された場所を特定し、追加された他のオブジェクトのhashcode
値。一致hashcode
するHashSet
ものがない場合は、オブジェクトが繰り返し表示されることはありません。 -
ただし、同じ
hashcode
値た場合は、equals()メソッドが呼び出されhashcode
、等しいオブジェクトが実際に同じであるかどうかがチェックされます。2つが同じである場合HashSet
、結合操作は成功しません。異なる場合は、他の場所で再ハッシュされます。 -
このようにして、回数
equals
を、実行速度を大幅に向上させます。
3. hashCode()メソッドとequals()メソッドの関係は何ですか?
Javaは、equals()メソッドとhashCode()メソッドを次のように定義しています。
- 同じオブジェクトでhashCode()メソッドを複数回呼び出すと、常に同じ整数値が返されます。
- 如果 a.equals(b),则一定有 a.hashCode() 一定等于 b.hashCode()。
- 如果 !a.equals(b),则 a.hashCode() 不一定等于 b.hashCode()。此时如果 a.hashCode() 总是不等于 b.hashCode(),会提高 hashtables 的性能。
- a.hashCode()==b.hashCode() 则 a.equals(b) 可真可假
- a.hashCode()!= b.hashCode() 则 a.equals(b) 为假。
上面结论简记:
- 如果两个对象 equals,Java 运行时环境会认为他们的 hashCode 一定相等。
- 如果两个对象不 equals,他们的 hashCode 有可能相等。
- 如果两个对象 hashCode 相等,他们不一定 equals。
- 如果两个对象 hashCode 不相等,他们一定不 equals。
4、为什么重写 equals 方法必须重写 hashcode 方法 ?
-
我们上面讲解到 如果 两个对象
equals
的话,那么它们的hashCode
值必然相等。如果只重写了equals
方法,而不重写hashCode
的方法,会造成hashCode
的值不同,而equals
方法判断出来的结果为true
。 -
在Java中的一些容器中,不允许有两个完全相同的对象,插入的时候,如果判断相同则会进行覆盖。这时候如果只重写了
equals
的方法,而不重写hashCode
的方法,Object中hashCode
是根据对象的存储地址转换而形成的一个哈希值。这时候就有可能因为没有重写hashCode
方法,造成相同的对象散列到不同的位置而造成对象的不能覆盖的问题。
例如
Dog类
package com.xiao;
/**
* @author :小肖
* @date :Created in 2022/3/11 14:42
*/
public class Dog {
private String name;
private Integer age;
public Dog() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Dog(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if(obj.getClass() != getClass()){
return false;
}
Dog dog = (Dog) obj;
if(dog.getAge() == age && dog.getName().equals(name)){
return true;
}
return false;
}
}
复制代码
测试类
import com.xiao.Dog;
public class Test {
public static void main(String[] args) {
Dog dog = new Dog("小旺",2);
Dog dog1 = new Dog("小旺",2);
System.out.println("equals结果:" + dog.equals(dog1));
System.out.println("dog 的 hashCode 值是否等于 dog1 的 hashCode 值:" +(dog.hashCode() == dog1.hashCode()));
}
}
复制代码
测试结果
equals结果:true
dog 的 hashCode 值是否等于 dog1 的 hashCode 值:false
复制代码