Java重写hashCode()的原则及方法

Java重写hashCode()方法有几个原则:

1、如果两个对象使用equals()方法比较,返回true(即相等),那么两个比较对象返回的hashCode()必须相等。

System.out.println(objA.equals(objB));
System.out.printlin(objA.hashCode() == objB.hashCode());

如果objA.equals(objB)为true,那么objA.hashCode== objB.hashCode()也一定为true。

2、多次调用同一对象的hashCode()方法,如果equals()方法里所使用的变量没有任何变化,那么必须返回相同的hashCode值。

User user = new User();
user.setAge(10);

int hash1 = user.hashCode();
int hash2 = user.hashCode();

user.setAge(11);
int hash3 = user.hashCode();

假如User的equals()方法使用了age计算,hash1和hash2,age的值同为10,没被修改,那么hash1和hash2相等。计算hash3前,age值修改为11,那么hash3的值可以与之前的hash1和hash2不等,也可以相等。

3、返回hashCode相等的对象,不一定equals()相等,也即是不同对象出现hash值碰撞。注意,一个好的hash算法应该让不同的对象有不同的hash值,这样会提高散列的性能。

重写方法

一般情况下,如果我们重写了类的equals()方法,最好也重写hashCode()方法,并且equals()方法里用到的成员变量也需要在hashCode()里做计算。

hashCode()返回的值对于使用散列存储的结构(如HashTable,HashSet,HashMap)的性能很重要,重写hashCode()方法最好是让不同的对象(即使用equals()不等),返回不同的hashCode的值。

Effective Java的作者推荐使用基于17和31的散列码的算法,如

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    User user = (User) o;

    if (!name.equals(user.name)) return false;
    return age == user.age;

}

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

Java 7新增的Objects类提供了计算hashCode的通用方法,可以很简洁实现hashCode

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    User user = (User) o;
    return Objects.equals(name, user.name) &&
            Objects.equals(age, user.age);
}

@Override
public int hashCode() {
    return Objects.hash(name,age);
}

版权声明:著作权归作者所有。

相关推荐

Java 10 var的使用及限制

在Java 10的众多特性里,局部变量的类型推断是比较受大家关注的特性之一。这里简单介绍下它的使用以及限制。在Java 7,声明一个列表我们会这样做:List<String> list = new ArrayList<String>(); Java 8/9可以改写为:List<String>&

Java获取受信任的根证书列表的方法

import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.KeyStore; import java.security.KeySt

Java 9 Stream新增方法takeWhile的bug

Java 9的Stream新增方法takeWile():允许我们返回Stream里满足条件的前面部分元素。如:String[] arr= {"a", "b", "c","d"}; Arrays.stream(arr)     &n

JavaScript跳转页面的方法及区别

JavaScript跳转页面主要有三种方法:1、location.replacelocation.replace会替换当前页面的history,这意味着不能使用后退按钮回退replace前的页面。window.location.replace("https://majing.io"); 有点类似模拟http请求的重定向2、location.assignlocation.assi

Java创建文件的常用方法

Java创建文件有几种常用的方法File.createNewFile()创建空白文件java.io.File类里的方法createNewFile()可以用来创建文件。createNewFile()新建的是空文件。创建文件首先要使用File类构建将要被创建的文件,然后再调用createNewFile()把新文件创建出来。createNewFile()的结果分为三种情况:新文件创建成功返回true。如

Java Objects.hash()与自己实现的hashCode()比较

Java 7新增了Objects类,它为对象提供了一些便捷的静态方法,如equals(),hashCode(),hash(),compare(),toString()等等。这里比较一下Objects.hash()与自己实现的hashCode()。传统实现的hashCode@Override public int hashCode() {  &nbs