
为什么要编写hashCode方法
hashCode在平时不常自己去编写,但是在真正高质量的代码中却是必不可少的。
看看Java中的Object对hashCode方法的描述:
1.返回对象的哈希码,是为了提高哈希表的性能,例如java.util.HashTable
2.同一个对象多次调用hashCode方法时,必须一致的返回相同的整数
3.若两个对象相等,则调用hashCode方法的时候必须返回相同的整数
不编写hashCode方法出现的情况
下面有这样的一个实体类:
/**
* @class User
* @introduction 实体类
* @author Ray_xujianguo
*/
public class User {
private String name; //姓名
private int age; //年龄
private long friendNumber; //朋友数目
private float cash; //现金
private double wealth; //财富
private boolean isMarry; //是否已婚 //无参数构造方法
public User() {} //有参数构造方法
public User(String name, int age, long friendNumber, float cash, double wealth, boolean isMarry) {
this.name = name;
this.age = age;
this.friendNumber = friendNumber;
this.cash = cash;
this.wealth = wealth;
this.isMarry = isMarry;
} @Override
public boolean equals(Object object) {
if(object instanceof User) {
User user = (User)object;
if(user.getName().equals(name) &&
user.getAge() == age &&
Long.compare(user.getFriendNumber(), friendNumber) == 0 &&
Float.compare(user.getCash(), cash) == 0 &&
Double.compare(user.getWealth(), wealth) == 0 &&
user.isMarry() == isMarry) {
return true;
} else {
return false;
}
} else {
return false;
}
} //getter and setter method
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;
} public long getFriendNumber() {
return friendNumber;
} public void setFriendNumber(long friendNumber) {
this.friendNumber = friendNumber;
} public float getCash() {
return cash;
} public void setCash(float cash) {
this.cash = cash;
} public double getWealth() {
return wealth;
} public void setWealth(double wealth) {
this.wealth = wealth;
} public boolean isMarry() {
return isMarry;
} public void setMarry(boolean isMarry) {
this.isMarry = isMarry;
}
}
这个实体类是重写了equals方法的,现在我们试图将其放进Map中,再将其拿出来。
@Test
public void testHashCode() {
Map<User, String> map = new HashMap<User, String>();
map.put(new User("xujianguo", 21, (long)1000, (float)12.5, (double)6000.25, false), "admin");
System.out.println(map.get(new User("xujianguo", 21, (long)1000, (float)12.5, (double)6000.25, false)));
}
这个的map存进去了一个User和String啊,根据这个User怎么拿不到呢,原因是因为这两个User的hashCode不一样,说到根本的东西就是调用hashCode方法没有返回一致的哈希码下面我们就来说说怎么编写hashCode方法。
编写hashCode方法
1.把某个非零的常数值,保存在一个名为result的int类型的常量中
2.属性域f哈希码c的计算
- 如果是boolean类型,true为1,false为0
- 如果是byte、char、short和int类型,强制为int的值
- 如果是long类型,计算(int)(f^(f>>32))
- 如果是float类型,计算Float.floatToIntBits(f)
- 如果是double类型,计算Double.doubleToLongBits(f),再按照long的方法进行计算
- 如果是引用类型,则调用其hashCode方法(假设其hashCode满足你的需求)
3.代入公式result = result * 31 + c
4.返回result
现在针对这User类来编写hashCode方法:
@Override
public int hashCode() {
int result = 17;
result = 37 * result + name.hashCode();
result = 37 * result + age;
result = 37 * result + (int)(friendNumber^(friendNumber>>32));
result = 37 * result + Float.floatToIntBits(cash);
result = 37 * result + (int)(Double.doubleToLongBits(wealth)^(Double.doubleToLongBits(wealth)>>32));
result = 37 * result + (isMarry ? 1 : 0);
return result;
}
加入了这个hashCode方法后,上面那个testHashCode方法就可以成功通过key拿出value了。