为什么在Java中2个对象有不同的哈希代码,而2个字符串有相同的哈希代码?

为什么在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()(用于

为什么str0和str1的哈希代码是相同的,而不是a和b?

因为
String
覆盖了
Object.hashCode()
,而您的类没有覆盖

这意味着
String
类有一个特定的
hashCode()
实现,该实现将基于
字符串
值计算哈希值。因此,对于具有相同值的两个字符串,哈希代码将是相同的

例如,当您创建一个新类时,
a
,如果您没有为
hashCode()
提供自己的实现,它将使用class
Object
中的默认实现。默认实现只能保证哈希代码在它们来自完全相同的实例时是相同的

方法
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;
}