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) 方法比较结果不等,可以相等也可以不相等。