哈希码哈希图和等于
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 之外,它还会检查两个对象是否相等,如果两个条件都满足,那么它将覆盖相同的键的值。
我哪里理解错了?
场景一:
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 之外,它还会检查两个对象是否相等,如果两个条件都满足,那么它将覆盖相同的键的值。