参考http://allenwei.javaeye.com/blog/228867 什么要重写hashCode方法? 我们应该先了解java判断两个对象是否相等的规则。 在java的集合中,判断两个对象是否相等的规则是: 首先,判断两个对象的hashCode是否相等如果不相等,认为两个对象也不相等 如果相等,则判断两个对象用equals运算是否相等 如果不相等,认为两个对象也不相等 如果相等,认为两个对象相等 我们在equals方法中需要向下转型,效率很低,所以先判断hashCode方法可以提高效率 如何重写hashCode方法呢? 你可以写Java代码 public int hashCode(){ return 42; } public int hashCode(){ return 42; } 这是一种符合规则的写法,保证了两个equal 的object 拥有相同的hashCode 但这种方法显然是不可取的 比较通用的做法是返回一个result Java代码 public int hashCode() { int result = 17; //任意素数 result = 31*result +c1; //c1,c2是什么看下文解释 result = 31*result +c2; return result; } public int hashCode() { int result = 17; //任意素数 result = 31*result +c1; //c1,c2是什么看下文解释 result = 31*result +c2; return result; } 其中c1,c2是我们生成的你要计算在内的字段的代码,生成规则如下:如果字段是boolean 计算为(f?1:0);如果字段是byte,char,short,int则计算为 (int)f;如果字段是long 计算为 (int)(f^(f>>32));如果字段是float 计算为 Float.floatToLongBits(f);如果字段是一个引用对象,那么直接调用对象的hashCode方法,如果需要判空,可以加上如果为空就返回0; 如果字段是一个数组则需要遍历所有元素,按上面几种方法计算; 当你写完后hashCode方法后问问自己1、是否两个equal的实例,拥有相同的jhashCode2、两个不同的实例,是否拥有相同的hashCode写一个JUnit Test 测试一下
think in java 里面有呢: 1.给int变量赋值 2.为对象中每个有意义的字段计算出一个散列码 3.合并 4.返回结果 5.验证结果,确保相同的对象有相同的散列码public class Test { private String s = null; private int id = 0; . . . public int hashCode() { int result = 17; result = 37 * result + s.hashCode(); result = 37 * result + id; return result; } }
那跟hashcode()方法对应的equals()方法的重写是像这个一样的吗? public class EntBlockGroup{ private int group_id; private String group_name; private int block_type_id; @Override public boolean equals(Object obj) { // TODO Auto-generated method stub return (obj instanceof EntBlockGroup)&&(group_id==((EntBlockGroup)obj).group_id)&&(block_type_id==((EntBlockGroup)obj).block_type_id); } }
package test;public class TestHashCode { private int a;
public TestHashCode(int b){ this.a = b; } // @Override // public int hashCode(){ // return a; // } @Override public boolean equals(Object o){ return o instanceof TestHashCode && (a == ((TestHashCode)o).a); } public int getA() { return a; } public void setA(int a) { this.a = a; } }public class Test { public static void main(String[] args){ //测试hashCode TestHashCode test1 = new TestHashCode(1); TestHashCode test2 = new TestHashCode(1); System.out.println(test1.equals(test2)); System.out.println(test1.hashCode()); System.out.println(test2.hashCode()); } } 我的这个重写的hashCode()方法貌似没起到作用...还望帮小弟解释下.
@Override public int hashCode(){ return a.hashCode(); }
什么要重写hashCode方法? 我们应该先了解java判断两个对象是否相等的规则。 在java的集合中,判断两个对象是否相等的规则是:
首先,判断两个对象的hashCode是否相等如果不相等,认为两个对象也不相等
如果相等,则判断两个对象用equals运算是否相等
如果不相等,认为两个对象也不相等
如果相等,认为两个对象相等 我们在equals方法中需要向下转型,效率很低,所以先判断hashCode方法可以提高效率 如何重写hashCode方法呢? 你可以写Java代码
public int hashCode(){
return 42;
} public int hashCode(){
return 42;
} 这是一种符合规则的写法,保证了两个equal 的object 拥有相同的hashCode 但这种方法显然是不可取的 比较通用的做法是返回一个result Java代码
public int hashCode() {
int result = 17; //任意素数
result = 31*result +c1; //c1,c2是什么看下文解释
result = 31*result +c2;
return result;
} public int hashCode() {
int result = 17; //任意素数
result = 31*result +c1; //c1,c2是什么看下文解释
result = 31*result +c2;
return result;
} 其中c1,c2是我们生成的你要计算在内的字段的代码,生成规则如下:如果字段是boolean 计算为(f?1:0);如果字段是byte,char,short,int则计算为 (int)f;如果字段是long 计算为 (int)(f^(f>>32));如果字段是float 计算为 Float.floatToLongBits(f);如果字段是一个引用对象,那么直接调用对象的hashCode方法,如果需要判空,可以加上如果为空就返回0;
如果字段是一个数组则需要遍历所有元素,按上面几种方法计算; 当你写完后hashCode方法后问问自己1、是否两个equal的实例,拥有相同的jhashCode2、两个不同的实例,是否拥有相同的hashCode写一个JUnit Test 测试一下
1.给int变量赋值
2.为对象中每个有意义的字段计算出一个散列码
3.合并
4.返回结果
5.验证结果,确保相同的对象有相同的散列码public class Test {
private String s = null;
private int id = 0;
.
.
.
public int hashCode() {
int result = 17;
result = 37 * result + s.hashCode();
result = 37 * result + id;
return result;
}
}
public class EntBlockGroup{
private int group_id;
private String group_name;
private int block_type_id; @Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
return (obj instanceof EntBlockGroup)&&(group_id==((EntBlockGroup)obj).group_id)&&(block_type_id==((EntBlockGroup)obj).block_type_id);
}
}
Object中的hashCode()方法在我们创建对象的时候为每个对象计算一个散列码,这个散列码是唯一的,所以如果2个对象的散列码相同,那他们一定是同一个对象。
自己定义的类也可以重写hashCode()方法,按照自己定义的算法计算散列码的生成。Object中的equals()方法,比较的是2个对象的引用地址,包括他们各自的散列码,如果不同,就认为是不同的对象。
String类中重写了equals方法,比较的是他们字符串的内容。
最好别自己写,让eclipse根据字段自动生成就好了
private int a;
public TestHashCode(int b){
this.a = b;
}
// @Override
// public int hashCode(){
// return a;
// }
@Override
public boolean equals(Object o){
return o instanceof TestHashCode && (a == ((TestHashCode)o).a);
} public int getA() {
return a;
} public void setA(int a) {
this.a = a;
}
}public class Test {
public static void main(String[] args){
//测试hashCode
TestHashCode test1 = new TestHashCode(1);
TestHashCode test2 = new TestHashCode(1);
System.out.println(test1.equals(test2));
System.out.println(test1.hashCode());
System.out.println(test2.hashCode());
}
}
我的这个重写的hashCode()方法貌似没起到作用...还望帮小弟解释下.
@Override
public int hashCode(){
return a.hashCode();
}