HashCode:
hashcode就是一个签名。当两个对象的hashcode一样时,两个对象就有可能一样。如果不一样的话两个对象就肯定不一样。
一般用hashcode来进行比较两个东西是不是一样的,可以很容易的排除许多不一样的东西。
最常用的地方就是在一堆东西里找一个东西。先用你要找的东西的hashcode和所有东西的hashcode比较,如果不一样的话就肯定不是你要找的东西。如果一样的话就很可能是你要找的东西。然后再进行仔细的比较两个东西是不是真的一模一样。
//一个不能加重复内容的容器
class Set {
Object[] objs = new Object[10]; //装东西的的数组
int size = 0; //已经有几个东西
//添加新东西,成功的话返回true,如果已经有了的话返回false
boolean add(Object o) {
for(int i=0;i<size;i++) { //搜索所有已经加进来的对象
if(objs[i].hashCode() == o.hashCode()) //如果hashcode一样的话就说明两个有可能是一样的
if(objs[i].equals(o)) return false; //仔细的确认一下是不是真的一样,如果一样的话就不加入这个对象
}
objs[size++]=o; //确认没有过这个东西,加入数组
return true;
}
}
当使用这个类的时候要确保两个一样的东西的hashcode肯定是一样的。两个不同的东西的hashcode可以是一样的,不过这样会减慢运行速度,所以尽量避免(也就是所谓的碰撞)。
如:HashSet中插入数据,只有当equals hashCode 都为true是才加入。
即对于HashMap HashSet等集合,只有当equals 和 hashcode都返回true,才认为是同一个对象。
hashset中元素数目
Hashcode true
equals false 有两个
Hashcode false
equals false 两个
Hashcode false
equals true 两个
Hashcode true
equals true 一个
public class Student { private int id; private String name; private int age; public Student(){} public Student(int id,String name,int age){ this.id=id; this.name=name; this.age=age; } public int getId() { return id; } public void setId(int id) { this.id = id; } 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; } @Override public boolean equals(Object obj) {//根据id判定是否相等 if(this==obj)return true; if(null==obj)return false; if(obj.getClass()!=getClass())return false; Student stu = (Student)obj; if(id!=stu.getId())return false; return true; } @Override public int hashCode() { return 18;//返回同一个hashcode } }
测试类:
public class HashCodeTest { public static void main(String[] args) { List<Student> stuList = new ArrayList<Student>(); Set<Student> stuSet = new HashSet<Student>(); Student st1 = new Student(1, "zhangsan", 18); Student st2 = new Student(1, "zhangsan", 18); stuList.add(st1); stuList.add(st2); stuSet.add(st1); stuSet.add(st2); System.out.println("st1==st2 "+(st1==st2)); System.out.println("st1.equals(st2) "+st1.equals(st2)); System.out.println("list size="+stuList.size()); System.out.println("set size="+stuSet.size()); //---------remove测试 System.out.println("remove测试"); System.out.println("remove result="+stuSet.remove(st2));//删除成功,为同一个对象 System.out.println("set size="+stuSet.size()); stuSet.add(st1); stuSet.add(st2); //让equals不相等,hashcode相等 st2.setId(2); System.out.println("remove测试"); System.out.println("remove result="+stuSet.remove(st2));//删除失败,st2的hashcode与equals不同时为true。即没找到要删除的对象 System.out.println("set size="+stuSet.size()); } }
测试结果:
st1==st2 false
st1.equals(st2) true
list size=2
set size=1
remove测试
remove result=true
set size=0
remove测试
remove result=false
set size=1