在每一个改写了equals()方法的类中,你必须也要改写hashCode()方法。 不这么做的话 违反了Object.hasCode()的通用约定,从而导致该类无法与所有基于散列值(hash)的集合类结合一起正常运作(如:HashMap HashSet 和HashTable)
java.lang.Object中约定的 hashCode的规范:
1.一个应用程序执行过程中,一个对象的equals方法所作比较的信息没有被修改的话,那么调用多次hashCode方法返回的应该是同一个整数
2.如果通过equals放比较的两个对象相等 那么 两个对象的hasCode()方法返回的值必须相同
3.比较的两个对象不相同 可以返回相同的hasCode() 但是我们做程序应该尽量保证他们不相同,提高hashtable的性能。。
例子:
这里重写了hashCode()散列函数,刚开始重写这个hasCode()方法的时候 我不知道如何去设计这个方法该返回什么值,根据一个好的散列函数的倾向:【为不相等的对象产生不同的散列码(hashCode)】..我抄袭了下一个简单的通用方法,当然可以自己设计:
1.把某个非零证书,比如这里的11 保存到一个result 的int变量中 (这个result就是用来组装最后返回的散列值的)
2.对于对象中每一个关键域(即equals方法中的进行比较的域 上例中的stepId和ResouceName)完成下面的操作:
a.进行散列值的计算 c :
i:boolean 类型的 f?0:1.
byte char short 或者int行的 直接就是 (int)f
long类型的(int)(f^(f>>>32))
float >> Float.floatToIntBits(f)
double>>(int)(Double.doubleToLongBits(f)^(Double.doubleToLongBits(f)>>>32))
如果是引用对象 如:String 直接或者别的类型 直接返回对象的 hasCode()方法,因此要记得引用对象也要有相应的hasCode()方法的重写 String类型的话 简单的调用下 String.hasCode()方法。
如果是数组的方法 循环每一个元素 按照上面给出来的规则去改写。
3.return 37*result + c;
完成了这个方法之后 多检查几遍 是否相等的对象具有相等的hasCode。。
上面出示话得值 11 是随便给的 可以根据自己的需要给出 为什么要给一个非零的初始值??我也不太明白 据说是可以避免一定的散列冲突。
其实上面那些我开始也不知道有啥用处,不就是判断是不是相等吗,有什么用吗? 其实挺有用的 比如:
我们要去除List中的一些对象的重复值(当然这个重复的标准由你的equals方法去确定) 你会怎么去做 ??
我们可以通过Set的特性,即没有重复的值 来快速进行去重复操作,而HashSet判断对象是否重复的标准就是equals()方法和hashCode()。所以重写hashCode()方法:
public class Test { public static void main(String[] args) { List list = new ArrayList(); StaticUserGroupBean bean1 = new StaticUserGroupBean(); bean1.setActionId(1); bean1.setResourceName("aaa"); bean1.setStepId(2); bean1.setUser(false); StaticUserGroupBean bean2 = new StaticUserGroupBean(); bean2.setActionId(1); bean2.setResourceName("aaa"); bean2.setStepId(3); bean2.setUser(false); list.add(bean1); list.add(bean2); System.out.println(bean1.hashCode()); System.out.println(bean2.hashCode()); System.out.println(bean1.equals(bean2)); list = removeCopys(list); for(int i = 0 ; i < list.size() ; i ++) { StaticUserGroupBean bean = (StaticUserGroupBean)list.get(i); System.out.println(bean.getActionId() + " " + bean.getResourceName() + " " + bean.getStepId()); } } //利用set的特性去除重复项 private static List removeCopys(List list) { Set set = new HashSet(list); //把list清空 list.clear(); //再把去掉了重复值的list添加进来 list.addAll(set); return list; } }