通俗来讲,哈希码就是唯一标识一个对象,首先明确一个概念,任何类都默认继承object类,哈希码具体来讲是通过一个哈希算法得到一个数字。我们首先来看看源码。
这是object的
public native int hashCode();
具体以String为例
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
实例分析
public class test3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Set<String> set=new HashSet<String>();
set.add("张三");
set.add("张三");
set.add("张三");
/* String name="张三";
set.add(name);*/
for (String string : set) {
System.out.println(string);
System.out.println(string.hashCode());
}
}
}
结果
张三
774889
由于String重写了string方法和equals方法,添加的对象由于哈希码相同,后又比较equals方法相同 ,发现内容相同故认为是同一个对象,不会重复添加。
我们再来看一个例子
package com;
import java.util.*;
public class HashSet3
{
public static void main(String[] args)
{
HashSet hs = new HashSet();
hs.add(new Person("a1",11));
hs.add(new Person("a2",12));
hs.add(new Person("a3",13));
hs.add(new Person("a2",12));
hs.add(new Person("a4",14));
Iterator it = hs.iterator();
while(it.hasNext())
{
Person p = (Person)it.next();
System.out.println(p.getName()+"::"+p.getAge()+"hashcode"+p.hashCode());
}
}
}
class Person
{
private String name;
private int age;
Person(String name,int age)
{
this.name = name;
this.age = age;
}
/* public int hashCode()
{
System.out.println(this.name+"....hashCode");
return name.hashCode()+age*37; //保证此元素的返回值尽量不一致。
}
public boolean equals(Object obj)
{
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
System.out.println(this.name+"...equals.."+p.name);
System.out.println(this.name.equals(p.name) && this.age == p.age);
return this.name.equals(p.name) && this.age == p.age;
}
*/
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
结果 可以发现实现上加入了两个a2,这两个a2信息都相同,实际上这是不科学的,按照正常来讲这个对象不能重复。
a3::13hashcode2018699554
a4::14hashcode118352462
a1::11hashcode366712642
a2::12hashcode1829164700
a2::12hashcode1311053135
把注释去掉后运行结果为,因为重写了equals方法和hashcode方法。这个结果就是正常的。
a1….hashCode
a2….hashCode
a3….hashCode
a2….hashCode
a2…equals..a2
true
a4….hashCode
a3….hashCode
a3::13hashcode3539
a1….hashCode
a1::11hashcode3463
a4….hashCode
a4::14hashcode3577
a2….hashCode
a2::12hashcode3501