哈希码哈希图和等于

hashcode hashmap and equals

我哪里理解错了?

场景一:

Float[] f1= new Float[2];
Float[] f2= new Float[2];
System.out.println("Values"+f1[0]+","+f2[0]+","+(f1==f2));

输出:0.0、0.0、假。

我从这里了解到的是:

1) 每当我们声明一个float类型的数组时,所有的值都被初始化为0.0

2) 虽然f1和f2的值相同,但它们指向堆中不同的地址。

3) Object Class 中的 .equals() 将 head 中值的地址与值进行比较。

    HashMap<String, Integer> hashMap = new HashMap();
    String str1 = new String("test");
    String str2 = new String("test");
    System.out.println((str1==str2));
    System.out.println((str1.hashCode()==str2.hashCode()));

    hashMap.put(str1,1);
    hashMap.put(str2,2);
    System.out.println(hashMap.get(str1));

输出:假 真的 2

场景二

我从这里了解到的是 1) 创建了两个不可变的字符串文字 "test" 。它们都指向内存中的不同位置

2) 来自 Oracle Docs,如果 equals 返回的值相同,则返回的哈希码值必须相同,反之亦然。因此,在第二个输出中偏离 equals 方法是合理的(即与 hashValue 相比)。 在这种情况下,hashCode 内部是如何工作的?不是比较地址吗?这里他们指向不同的位置,所以他们应该有不同的地址吧?

3) 它们具有相同的 hashCode,因此 hashMap 正在用 str2 替换 str1 的值。

场景 #1
1) 每当我们声明一个 float 类型数组时,所有值都被初始化为 0.0
没错

2) 虽然f1和f2的值相同,但它们指向堆中不同的地址。
是的,您正在比较堆中两个数组的引用。

3) Object Class 中的 .equals() 将 head 中值的地址与值进行比较。
是的,它与上面#2 的答案相同。它比较两个对象的引用。

场景 #2
1) 创建了两个不可变字符串文字 "test"。它们都指向内存中的不同位置
是的,没错。

2) 来自 Oracle Docs,如果 equals 返回的值相同,则返回的哈希码值必须相同,反之亦然。因此,在第二个输出中偏离 equals 方法是合理的(即与 hashValue 相比)。在这种情况下,hashCode 在内部是如何工作的?不是比较地址吗?他们在这里指向不同的位置,所以他们应该有不同的地址,对吗?

这就是 hashCode 方法对字符串的作用方式:

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

3) 它们具有相同的 hashCode,因此 hashMap 正在用 str2 替换 str1 的值。
除了 hashCode 之外,它还会检查两个对象是否相等,如果两个条件都满足,那么它将覆盖相同的键的值。