1.概念:
hashcode(散列码)是由对象导出的一个整型值,hashcode是没有规律的。如果x和y是两个不同的对象,则x.hashcode域y.hashcode基本上不会相同。
2.实例
具体请看
String s ="ok";
StringBuilder sBuilder =new StringBuilder(s);
System.out.println(s.hashCode()+" "+sBuilder.hashCode());
String b ="ok";
StringBuilder bBuilder =new StringBuilder(b);
System.err.println(b.hashCode()+" "+bBuilder.hashCode());
String s 和StringBuilder s是两个不同的对象所以基本不相同
那么为什么 s和b一样呢,注意 拥有相同的hashcode是因为字符串的散列码是由内容导出的。而sBulider,bBulider有不同的
散列码是因为StringBuffer类中没有定义hashcode方法,他的hashcode是由Object类的默认方法导出对象的存储地址
还有,如果重新定义equals方法,就必须重新定义hashcode方法,一变用户可以将对象插入到散列表中
3.散列码怎么表示
每一个点就代表一个散列码,使用合理的实例域,的散列码,让对象产生的散列码更加均匀
质数是尽量散列的
4.计算:
通常我们通过一个对象hashCode方法可以获取这个对象的哈希码,但是有些时候我们需要自己来实现hashCode方法,自己来通过一个数学公式来计算每一个对象的hashCode。
那什么时候需要自己来hashCode方法呢?
通常来说,如果我们重写了equals方法,就必须实现hashCode,因为如果x.equals(y)返回的是true的话,那么x.hashCode()就必须与y.hashCode()方法具有相同的值。
通常我们可以通过下面几种方式来计算hashCode。
首先我们假设一个Employee类:
public class Employee
{
private String name = null;
private double salary = 0;
private String hireDay = null;
public Employee(String name, double salary, String hireDay)
{ this.name = name;
this.salary = salary;
this.hireDay = hireDay; }
public String getName()
{ return name; }
public void setName(String name)
{ this.name = name; }
public double getSalary()
{ return salary; }
public void setSalary(double salary)
{ this.salary = salary; }
public String getHireDay()
{ return hireDay; }
public void setHireDay(String hireDay)
{ this.hireDay = hireDay; }
}
如果我们重写equals方法,同时设置比较的规则,假设值有当name和salary相同时(这里没有比较hireDay属性),就表示这两个对象是相同的。那么我们在重写hashCode方法时,必须只能通过name和salary两个属性来生成hashCode。
5.派生类的重写
1.普通方法:
@Override
public int hashCode()
{ //因为这里salry是double基本数据类型,所以这里需要转换成为Double类型
//因为equals只需要比较name和salary,所以这里只需要生成name和salary的hashCode就行了
return 7 * name.hashCode() + 11 * new Double(salary).hashCode();
}
2.objects类:
@Override
public int hashCode() {
return 7 * Objects.hashCode(name) + 11 * Double.hashCode(salary);
}
3.Objectds类中的hash方法
@Override
public int hashCode() {
return Objects.hash(name, salary);
}