30、hashCode方法

HashCode方法的作用

在HashSet中的元素是不能重复的,jvm可以通过equals方法来判断两个对象是否相同,假设自定义一个Person类里面有10个成员变量,每调用一次equals方法需要做10次if判断分别比较这10个成员变量是否相等,如果想HashSet中存放100个对象,那就会做1000次if判断,数据量大的话会严重影响性能。
要解决这个问题的话可以这样做,将一些特征相似或相近的对象归类放到一起给他们一个编号,在做equals判断时,先比较这些编号,编号相同的话再去比较equals,这样可以减少一些比较次数。这个编号可以通过HashCode方法获得。HashCode方法的作用就是将对象进行分类,然后获取到编号值。
举个例子,图书馆里面的书都是分好类的,想找《java编程思想》这本书,先找到计算机类的书架,然后再去找就行,倘若图书馆里面的书籍没有分类,那找起来就如大海捞针。

如何重写HashCode

HashCode算法决定了对象的归类,如果算法编写的不好可能不会对性能有所提升。在编写时最好可以让对象均匀的散列开,这里假设可以将对象分为10个种类,那么每个种类中存放的对象的数量最好不要相差太多。
这里以Person类为例:

package com.monkey1024.bean;

/**
 * Person类
 *
 */
public class Person {

    private String name;
    private int age;

    public Person() {

    }

    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

}

将Person的name和age属性都加上了,可以将Person进行细分,开发中建议使用:

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + age;
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    return result;
}

为什么上面的prime的值是31?其实这个值改成别的也可以,只不过定义为31之后有一些好处:

  • 31是一个质数,质数是能被1和自己本身整除的数,并且这个数不大也不小
  • 31这个数好算,2的五次方-1,2向左移动5位

关于重写HashCode方法的一些说明

任何时候对同一对象多次调用 hashCode 方法,都必须一直返回同样的整数。

如果两个对象通过 equals(Object) 方法来比较相等,那么这两个对象的 hashCode的值必须相等。

如果两个对象通过 equals(Object) 方法比较结果不等,可以相等也可以不相等。

 

原文地址:https://www.cnblogs.com/zhuifeng-mayi/p/10135347.html