这个hashCode()方法起什么作用?怎样用在我们的编程中?
11 个解决方案
#1
这个方法是计算该对象的散列值,在Hashtable,HashMap这类使用散列值的地方用得着,如果使用容器,建立实例池,最常见的比如自己的entityBean primaryKey Class也用的着。
一般来说a.equal(b)==true => a.hashcode()==b.hashcode(),反之则未必。但是如果a.equal(b)==true <=> a.hashcode()==b.hashcode()推论成立则会大大提高效率。
一般来说a.equal(b)==true => a.hashcode()==b.hashcode(),反之则未必。但是如果a.equal(b)==true <=> a.hashcode()==b.hashcode()推论成立则会大大提高效率。
#2
我觉得差不多类似于给对象的一个编号
#3
同意asdmonster(努力学习VC,讨回失去的信誉分).
在Hashtable,HashMap这类使用散列值的类里,查找的时候可以直接使用hashCode,而不必要一个的遍历,这样一来效率提高很多.
在Hashtable,HashMap这类使用散列值的类里,查找的时候可以直接使用hashCode,而不必要一个的遍历,这样一来效率提高很多.
#4
先谢谢 asdmonster(努力学习VC,讨回失去的信誉分) 的回答,回答透切,但是关于此问题我还有些别的想法:
这样看来,Object.hashCode()得出的散列值是为了用于在容器中查找对象提高效率,不知java的设计者把这样一个方法放在基类Object里是不是合适?这意味着java中的每个对象都有一个散列值,但是这个散列值并不能唯一标志一个对象(因为虽然a<>b,但a.euqal(b)==true时,也会存在a.hashCode()==b.hashCoede()),并且这个散列值的产生由jvm计算出来,我们好象不能控制其值是多少,也不知道它产生的规律,好象此方法并不具有普遍性,而放在Object这样的基类里面,我觉得不算怎么合适!!
to : asdmonster(努力学习VC,讨回失去的信誉分)
"但是如果a.equal(b)==true <=> a.hashcode()==b.hashcode()推论成立则会大大提高效率。"
------ 你这句话是什么意思?
这样看来,Object.hashCode()得出的散列值是为了用于在容器中查找对象提高效率,不知java的设计者把这样一个方法放在基类Object里是不是合适?这意味着java中的每个对象都有一个散列值,但是这个散列值并不能唯一标志一个对象(因为虽然a<>b,但a.euqal(b)==true时,也会存在a.hashCode()==b.hashCoede()),并且这个散列值的产生由jvm计算出来,我们好象不能控制其值是多少,也不知道它产生的规律,好象此方法并不具有普遍性,而放在Object这样的基类里面,我觉得不算怎么合适!!
to : asdmonster(努力学习VC,讨回失去的信誉分)
"但是如果a.equal(b)==true <=> a.hashcode()==b.hashcode()推论成立则会大大提高效率。"
------ 你这句话是什么意思?
#5
你问的东西我也不太了解,只能说说我的理解吧:
java.lang.Object的约定如下:
1,在程序的同一执行期间,如果equals方法的信息不给修改,那么对同一对象多次调用hashcode得出的值也是必须一样。但是不要求在不同的执行期间保持一致
2,如果两个对象的equals()方法等同,那么两对象任何一个调用hashCode()方法,必须产生同样的结果。
3,如果两对象的equals()方法不相等,那么对两对象的任意对象调用hashCode()方法,不要求产生两个不同的整数结果
hashcode 就仿佛是一个Object的ID,如果说它有什么特别,那就是它是一个int类型的值。在所有对象的运算中,int是最快(当然最快的是char,但是它能表达的信息太有限了)。一个简单的例子是Hashtable.contain(Object)方法,它首先是根据Object的散列值去判断,只有当出现多个相同的散列值的时候才会调用equals(),因为判断int比判断Object.equals()要快很多,这是一个提高效率的策略问题。同样也说明为什么不同的对象(equals()得false)具有不同的hashcode(也就是a.equal(b)==true <=> a.hashcode()==b.hashcode())具有更高效率的理由——不需要进行额外的equals()操作。
我的理解大致如此,更多的希望大家共同探讨。
java.lang.Object的约定如下:
1,在程序的同一执行期间,如果equals方法的信息不给修改,那么对同一对象多次调用hashcode得出的值也是必须一样。但是不要求在不同的执行期间保持一致
2,如果两个对象的equals()方法等同,那么两对象任何一个调用hashCode()方法,必须产生同样的结果。
3,如果两对象的equals()方法不相等,那么对两对象的任意对象调用hashCode()方法,不要求产生两个不同的整数结果
hashcode 就仿佛是一个Object的ID,如果说它有什么特别,那就是它是一个int类型的值。在所有对象的运算中,int是最快(当然最快的是char,但是它能表达的信息太有限了)。一个简单的例子是Hashtable.contain(Object)方法,它首先是根据Object的散列值去判断,只有当出现多个相同的散列值的时候才会调用equals(),因为判断int比判断Object.equals()要快很多,这是一个提高效率的策略问题。同样也说明为什么不同的对象(equals()得false)具有不同的hashcode(也就是a.equal(b)==true <=> a.hashcode()==b.hashcode())具有更高效率的理由——不需要进行额外的equals()操作。
我的理解大致如此,更多的希望大家共同探讨。
#6
string object 的hashcode能够被计算s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
n是长度。
其实我也有一个问题,字符计算成hashcode后把他存到数据库中再度出来是不是还是原来的东西,他是自动转换的吗,请大虾解答。
请楼主将贴子提前,借光一下。
n是长度。
其实我也有一个问题,字符计算成hashcode后把他存到数据库中再度出来是不是还是原来的东西,他是自动转换的吗,请大虾解答。
请楼主将贴子提前,借光一下。
#7
q 不知java的设计者把这样一个方法放在基类Object里是不是合适
a 放在Object里当然合适了,上面提到的Hashtable,HashMap甚么的保存的对象的类型都是java.lang.Object,如果Object里没有hashCode(),试问,别人如何调用?
q 但是这个散列值并不能唯一标志一个对象
a 只要你不乱改Object.hashCode(),是不会出现这个情况的,因为在Object中hashCode()是native的,它得到的值是与这个对象在内存中的地质有关,因此不会存在一个hashcode同事为两个对象所有的情况
q 好象不能控制其值是多少
a 可以控制阿,只要你覆盖了public int hashCode()方法,自己根据这个对象的情况返回一个int就可以了,当然这个值的计算需要进行很好的设计,保证其离散,减少重复值出现的可能性。
我这里有一个计算hashCode比较简单,但又相对有效的方法
public class YourObject{
int x;
int y;
Object another;
XXX xObject;
YYY yObject;
.......
public String toString(){
StringBuffer buf = new StringBuffer("YourObject[");
buf.append("x=").append(x).append(", ");
buf.append("y=").append(y).append(", ");
buf.append("another=").append(another).append(", ");
buf.append("xObject=").append(xObject).append(", ");
buf.append("yObject=").append(yObject).append(", ");
........
return buf.toString();
}
public int hashCode(){
return toString().hashCode() + 1; // -1 取反,等等
}
}
a 放在Object里当然合适了,上面提到的Hashtable,HashMap甚么的保存的对象的类型都是java.lang.Object,如果Object里没有hashCode(),试问,别人如何调用?
q 但是这个散列值并不能唯一标志一个对象
a 只要你不乱改Object.hashCode(),是不会出现这个情况的,因为在Object中hashCode()是native的,它得到的值是与这个对象在内存中的地质有关,因此不会存在一个hashcode同事为两个对象所有的情况
q 好象不能控制其值是多少
a 可以控制阿,只要你覆盖了public int hashCode()方法,自己根据这个对象的情况返回一个int就可以了,当然这个值的计算需要进行很好的设计,保证其离散,减少重复值出现的可能性。
我这里有一个计算hashCode比较简单,但又相对有效的方法
public class YourObject{
int x;
int y;
Object another;
XXX xObject;
YYY yObject;
.......
public String toString(){
StringBuffer buf = new StringBuffer("YourObject[");
buf.append("x=").append(x).append(", ");
buf.append("y=").append(y).append(", ");
buf.append("another=").append(another).append(", ");
buf.append("xObject=").append(xObject).append(", ");
buf.append("yObject=").append(yObject).append(", ");
........
return buf.toString();
}
public int hashCode(){
return toString().hashCode() + 1; // -1 取反,等等
}
}
#8
其实我也有一个问题,字符计算成hashcode后把他存到数据库中再度出来是不是还是原来的东西,他是自动转换的吗,请大虾解答。
你的理解错了,将对象计算成hashcode是位了决定把这个对象存放的位置,便于以后查找这个对象时到这个HashMap(不是数据库)或其他里面的由这个查找对象的hashCode所对应的位置去找,这个位置上有,就是找到了,没有就是没有,而不用从头一个一个进行比较。当然前提是将位置冲突解决好。
转乘hashcode是不可逆的,你想想看,全世界的各种语言,说出的各种String,有多少种可能的组合,而int类型才有多少种组合。显然是String>>int,因此一个String对应了一个hashCode,但一个hashCode可能对应了武术种可能的String
你的理解错了,将对象计算成hashcode是位了决定把这个对象存放的位置,便于以后查找这个对象时到这个HashMap(不是数据库)或其他里面的由这个查找对象的hashCode所对应的位置去找,这个位置上有,就是找到了,没有就是没有,而不用从头一个一个进行比较。当然前提是将位置冲突解决好。
转乘hashcode是不可逆的,你想想看,全世界的各种语言,说出的各种String,有多少种可能的组合,而int类型才有多少种组合。显然是String>>int,因此一个String对应了一个hashCode,但一个hashCode可能对应了武术种可能的String
#9
嗯,是我错了,我们可以覆盖hashCode()方法来自已返回一个散列值,不过我想我们应该没有哪个人会去干这种事情了。
#10
没有必要,不要去覆盖那些方法 .equals(),hashCode()(如果你重载了前者,后者必须随之更改),都是些费力不讨好的事。
#11
ok,谢谢All
#1
这个方法是计算该对象的散列值,在Hashtable,HashMap这类使用散列值的地方用得着,如果使用容器,建立实例池,最常见的比如自己的entityBean primaryKey Class也用的着。
一般来说a.equal(b)==true => a.hashcode()==b.hashcode(),反之则未必。但是如果a.equal(b)==true <=> a.hashcode()==b.hashcode()推论成立则会大大提高效率。
一般来说a.equal(b)==true => a.hashcode()==b.hashcode(),反之则未必。但是如果a.equal(b)==true <=> a.hashcode()==b.hashcode()推论成立则会大大提高效率。
#2
我觉得差不多类似于给对象的一个编号
#3
同意asdmonster(努力学习VC,讨回失去的信誉分).
在Hashtable,HashMap这类使用散列值的类里,查找的时候可以直接使用hashCode,而不必要一个的遍历,这样一来效率提高很多.
在Hashtable,HashMap这类使用散列值的类里,查找的时候可以直接使用hashCode,而不必要一个的遍历,这样一来效率提高很多.
#4
先谢谢 asdmonster(努力学习VC,讨回失去的信誉分) 的回答,回答透切,但是关于此问题我还有些别的想法:
这样看来,Object.hashCode()得出的散列值是为了用于在容器中查找对象提高效率,不知java的设计者把这样一个方法放在基类Object里是不是合适?这意味着java中的每个对象都有一个散列值,但是这个散列值并不能唯一标志一个对象(因为虽然a<>b,但a.euqal(b)==true时,也会存在a.hashCode()==b.hashCoede()),并且这个散列值的产生由jvm计算出来,我们好象不能控制其值是多少,也不知道它产生的规律,好象此方法并不具有普遍性,而放在Object这样的基类里面,我觉得不算怎么合适!!
to : asdmonster(努力学习VC,讨回失去的信誉分)
"但是如果a.equal(b)==true <=> a.hashcode()==b.hashcode()推论成立则会大大提高效率。"
------ 你这句话是什么意思?
这样看来,Object.hashCode()得出的散列值是为了用于在容器中查找对象提高效率,不知java的设计者把这样一个方法放在基类Object里是不是合适?这意味着java中的每个对象都有一个散列值,但是这个散列值并不能唯一标志一个对象(因为虽然a<>b,但a.euqal(b)==true时,也会存在a.hashCode()==b.hashCoede()),并且这个散列值的产生由jvm计算出来,我们好象不能控制其值是多少,也不知道它产生的规律,好象此方法并不具有普遍性,而放在Object这样的基类里面,我觉得不算怎么合适!!
to : asdmonster(努力学习VC,讨回失去的信誉分)
"但是如果a.equal(b)==true <=> a.hashcode()==b.hashcode()推论成立则会大大提高效率。"
------ 你这句话是什么意思?
#5
你问的东西我也不太了解,只能说说我的理解吧:
java.lang.Object的约定如下:
1,在程序的同一执行期间,如果equals方法的信息不给修改,那么对同一对象多次调用hashcode得出的值也是必须一样。但是不要求在不同的执行期间保持一致
2,如果两个对象的equals()方法等同,那么两对象任何一个调用hashCode()方法,必须产生同样的结果。
3,如果两对象的equals()方法不相等,那么对两对象的任意对象调用hashCode()方法,不要求产生两个不同的整数结果
hashcode 就仿佛是一个Object的ID,如果说它有什么特别,那就是它是一个int类型的值。在所有对象的运算中,int是最快(当然最快的是char,但是它能表达的信息太有限了)。一个简单的例子是Hashtable.contain(Object)方法,它首先是根据Object的散列值去判断,只有当出现多个相同的散列值的时候才会调用equals(),因为判断int比判断Object.equals()要快很多,这是一个提高效率的策略问题。同样也说明为什么不同的对象(equals()得false)具有不同的hashcode(也就是a.equal(b)==true <=> a.hashcode()==b.hashcode())具有更高效率的理由——不需要进行额外的equals()操作。
我的理解大致如此,更多的希望大家共同探讨。
java.lang.Object的约定如下:
1,在程序的同一执行期间,如果equals方法的信息不给修改,那么对同一对象多次调用hashcode得出的值也是必须一样。但是不要求在不同的执行期间保持一致
2,如果两个对象的equals()方法等同,那么两对象任何一个调用hashCode()方法,必须产生同样的结果。
3,如果两对象的equals()方法不相等,那么对两对象的任意对象调用hashCode()方法,不要求产生两个不同的整数结果
hashcode 就仿佛是一个Object的ID,如果说它有什么特别,那就是它是一个int类型的值。在所有对象的运算中,int是最快(当然最快的是char,但是它能表达的信息太有限了)。一个简单的例子是Hashtable.contain(Object)方法,它首先是根据Object的散列值去判断,只有当出现多个相同的散列值的时候才会调用equals(),因为判断int比判断Object.equals()要快很多,这是一个提高效率的策略问题。同样也说明为什么不同的对象(equals()得false)具有不同的hashcode(也就是a.equal(b)==true <=> a.hashcode()==b.hashcode())具有更高效率的理由——不需要进行额外的equals()操作。
我的理解大致如此,更多的希望大家共同探讨。
#6
string object 的hashcode能够被计算s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
n是长度。
其实我也有一个问题,字符计算成hashcode后把他存到数据库中再度出来是不是还是原来的东西,他是自动转换的吗,请大虾解答。
请楼主将贴子提前,借光一下。
n是长度。
其实我也有一个问题,字符计算成hashcode后把他存到数据库中再度出来是不是还是原来的东西,他是自动转换的吗,请大虾解答。
请楼主将贴子提前,借光一下。
#7
q 不知java的设计者把这样一个方法放在基类Object里是不是合适
a 放在Object里当然合适了,上面提到的Hashtable,HashMap甚么的保存的对象的类型都是java.lang.Object,如果Object里没有hashCode(),试问,别人如何调用?
q 但是这个散列值并不能唯一标志一个对象
a 只要你不乱改Object.hashCode(),是不会出现这个情况的,因为在Object中hashCode()是native的,它得到的值是与这个对象在内存中的地质有关,因此不会存在一个hashcode同事为两个对象所有的情况
q 好象不能控制其值是多少
a 可以控制阿,只要你覆盖了public int hashCode()方法,自己根据这个对象的情况返回一个int就可以了,当然这个值的计算需要进行很好的设计,保证其离散,减少重复值出现的可能性。
我这里有一个计算hashCode比较简单,但又相对有效的方法
public class YourObject{
int x;
int y;
Object another;
XXX xObject;
YYY yObject;
.......
public String toString(){
StringBuffer buf = new StringBuffer("YourObject[");
buf.append("x=").append(x).append(", ");
buf.append("y=").append(y).append(", ");
buf.append("another=").append(another).append(", ");
buf.append("xObject=").append(xObject).append(", ");
buf.append("yObject=").append(yObject).append(", ");
........
return buf.toString();
}
public int hashCode(){
return toString().hashCode() + 1; // -1 取反,等等
}
}
a 放在Object里当然合适了,上面提到的Hashtable,HashMap甚么的保存的对象的类型都是java.lang.Object,如果Object里没有hashCode(),试问,别人如何调用?
q 但是这个散列值并不能唯一标志一个对象
a 只要你不乱改Object.hashCode(),是不会出现这个情况的,因为在Object中hashCode()是native的,它得到的值是与这个对象在内存中的地质有关,因此不会存在一个hashcode同事为两个对象所有的情况
q 好象不能控制其值是多少
a 可以控制阿,只要你覆盖了public int hashCode()方法,自己根据这个对象的情况返回一个int就可以了,当然这个值的计算需要进行很好的设计,保证其离散,减少重复值出现的可能性。
我这里有一个计算hashCode比较简单,但又相对有效的方法
public class YourObject{
int x;
int y;
Object another;
XXX xObject;
YYY yObject;
.......
public String toString(){
StringBuffer buf = new StringBuffer("YourObject[");
buf.append("x=").append(x).append(", ");
buf.append("y=").append(y).append(", ");
buf.append("another=").append(another).append(", ");
buf.append("xObject=").append(xObject).append(", ");
buf.append("yObject=").append(yObject).append(", ");
........
return buf.toString();
}
public int hashCode(){
return toString().hashCode() + 1; // -1 取反,等等
}
}
#8
其实我也有一个问题,字符计算成hashcode后把他存到数据库中再度出来是不是还是原来的东西,他是自动转换的吗,请大虾解答。
你的理解错了,将对象计算成hashcode是位了决定把这个对象存放的位置,便于以后查找这个对象时到这个HashMap(不是数据库)或其他里面的由这个查找对象的hashCode所对应的位置去找,这个位置上有,就是找到了,没有就是没有,而不用从头一个一个进行比较。当然前提是将位置冲突解决好。
转乘hashcode是不可逆的,你想想看,全世界的各种语言,说出的各种String,有多少种可能的组合,而int类型才有多少种组合。显然是String>>int,因此一个String对应了一个hashCode,但一个hashCode可能对应了武术种可能的String
你的理解错了,将对象计算成hashcode是位了决定把这个对象存放的位置,便于以后查找这个对象时到这个HashMap(不是数据库)或其他里面的由这个查找对象的hashCode所对应的位置去找,这个位置上有,就是找到了,没有就是没有,而不用从头一个一个进行比较。当然前提是将位置冲突解决好。
转乘hashcode是不可逆的,你想想看,全世界的各种语言,说出的各种String,有多少种可能的组合,而int类型才有多少种组合。显然是String>>int,因此一个String对应了一个hashCode,但一个hashCode可能对应了武术种可能的String
#9
嗯,是我错了,我们可以覆盖hashCode()方法来自已返回一个散列值,不过我想我们应该没有哪个人会去干这种事情了。
#10
没有必要,不要去覆盖那些方法 .equals(),hashCode()(如果你重载了前者,后者必须随之更改),都是些费力不讨好的事。
#11
ok,谢谢All