未重写 hashCode 和 equals
public class ObjectDemo {
static class MyClass {
public String name;
}
public static void main(String[] args) {
MyClass myClass1 = new MyClass();
System.out.println(myClass1);
System.out.println("============");
Map<MyClass, String> map = new HashMap<>();
map.put(myClass1, "123");
System.out.println(map.get(myClass1));
System.out.println("============");
myClass1.name = "hello";
System.out.println(myClass1);
System.out.println(map.get(myClass1));
}
}
重写 hashCode 和 equals
public class ObjectDemo {
static class MyClass {
public String name;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyClass myClass = (MyClass) o;
return Objects.equals(name, myClass.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
public static void main(String[] args) {
MyClass myClass1 = new MyClass();
System.out.println(myClass1);
System.out.println("============");
Map<MyClass, String> map = new HashMap<>();
map.put(myClass1, "123");
System.out.println(map.get(myClass1));
System.out.println("============");
myClass1.name = "hello";
System.out.println(myClass1);
System.out.println(map.get(myClass1));
}
}
结论:
Obejct 的 equals 方法的实现为 使用 == 运算符比较两个对象
当 == 用于比较两个对象时,实际比较的是 对象在方法区 中的地址
Object 的 hashCode 方法为 native 方法,只确定和 对象在堆中的地址有关,但不完全就是 堆中的地址
如果一个对象(未重写 hashCode 和 equals),即改变对象中的成员属性等不会使对象的 hashCode 改变,那么不影响 Map.get() 方法获取到的结果
如果一个对象(重写了 hashCode 和 equals),那么改变对象中的成员属性会导致对象的 hashCode 造成改变,那么 Map.get() 方法获取的结果将受到影响
说明
1、Map 的 get 方法会根据对象的 hashCode 计算出 hash 值,从而得到哈希桶的位置(Entry 数组下标的编号)2、重写 equals 时必须重写 hashCode 方法,Java 规范中要求,equal 对象的 hashCode 必须相同(hashCode 相同,不一定 equal)