为什么在Java中2个对象有不同的哈希代码,而2个字符串有相同的哈希代码?
为什么str0和str1的哈希代码是相同的,而不是a和b?因为为什么在Java中2个对象有不同的哈希代码,而2个字符串有相同的哈希代码?,java,dictionary,hash,hashmap,Java,Dictionary,Hash,Hashmap,为什么str0和str1的哈希代码是相同的,而不是a和b?因为String覆盖了Object.hashCode(),而您的类没有覆盖 这意味着String类有一个特定的hashCode()实现,该实现将基于字符串值计算哈希值。因此,对于具有相同值的两个字符串,哈希代码将是相同的 例如,当您创建一个新类时,a,如果您没有为hashCode()提供自己的实现,它将使用classObject中的默认实现。默认实现只能保证哈希代码在它们来自完全相同的实例时是相同的 方法Objects.hash()(用于
String
覆盖了Object.hashCode()
,而您的类没有覆盖
这意味着String
类有一个特定的hashCode()
实现,该实现将基于字符串
值计算哈希值。因此,对于具有相同值的两个字符串,哈希代码将是相同的
例如,当您创建一个新类时,a
,如果您没有为hashCode()
提供自己的实现,它将使用classObject
中的默认实现。默认实现只能保证哈希代码在它们来自完全相同的实例时是相同的
方法Objects.hash()
(用于多个值)和Objects.hashCode()
(用于单个值)使得在您自己的类中实现hashCode()
更加容易。例如:
class A{
int a;
A(){
this.a = 100;
}
}
//in main, we have:
A a = new A(), b = new A();
//and
String str0 = "123", str1 = "123";
请注意,如果用于创建哈希的属性的值在某个点发生更改,则
hashCode()
的结果也可能会更改。因为java.lang.String
类中的hashCode()
的实现被覆盖
为了能够在集合中使用
String
s,必须重写实现。因为String的hashCode实现已构建为始终以给定顺序为同一字符集合返回相同的hash代码。而Object.hashCode()将任何对象都视为唯一的。如果您想知道两个字符串是否是不同的对象,那么可以使用Objects.hashCode(someString)
/**
*返回此字符串的哈希代码。函数的哈希代码
*{@code String}对象计算为
*
*s[0]*31^(n-1)+s[1]*31^(n-2)+…+s[n-1]
*
*使用{@code int}算术,其中{@code s[i]}是
*字符串的第i个字符,{@code n}是
*字符串,{@code^}表示求幂。
*(空字符串的哈希值为零。)
*
*@返回此对象的哈希代码值。
*/
公共int hashCode(){
int h=散列;
如果(h==0&&value.length>0){
char val[]=值;
for(int i=0;i
str0和str1指向StringPool中的同一引用,而'a'和'b'指向内存中的不同引用,因为使用了'new'关键字。这与字符串内部处理无关。@Crazyjavahacking确实如此。即使String
没有覆盖hashCode
,OP也会得到相同的结果,因为str1
和str2
是对同一对象的引用,而a
和b
不是。你在混淆概念。如果对象相等,hashCode()必须返回相同的值,就是这样。在这里,实习并不重要,因为对象无论如何都是相等的。@pbabcdef但它确实覆盖了hashCode,
,这就是实习不相关的原因。
class A{
int a;
A() {
this.a = 100;
}
@Override
public int hashCode() {
return Objects.hashCode(a);
}
}
/**
* Returns a hash code for this string. The hash code for a
* {@code String} object is computed as
* <blockquote><pre>
* s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
* </pre></blockquote>
* using {@code int} arithmetic, where {@code s[i]} is the
* <i>i</i>th character of the string, {@code n} is the length of
* the string, and {@code ^} indicates exponentiation.
* (The hash value of the empty string is zero.)
*
* @return a hash code value for this object.
*/
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;
}