java - Java检查内存地址中==运算符的作用

标签 java hashmap equals hashcode

直到今天,我仍然相信两个具有相同哈希码的对象意味着它们都具有相同的内存位置。但下面的代码讲述了一个完全不同的故事:

学生实体: 公共(public)类 Student 实现 Comparable {

int id;
int marks;
String Subject;

public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}
public int getMarks() {
    return marks;
}
public void setMarks(int marks) {
    this.marks = marks;
}
public String getSubjects() {
    return Subject;
}
public void setSubject(String subject) {
    Subject = subject;
}

public Student() {

}
public Student(int id, String subject, int marks) {
    super();
    this.id = id;
    this.marks = marks;
    Subject = subject;
}
@Override
public int compareTo(Student o) {
    if (this.getId()>(o.getId()))
    return 1;

    if (this.getId()<(o.getId()))
    return -1;

    return 1;
}

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((Subject == null) ? 0 : Subject.hashCode());
        result = prime * result + id;
        result = prime * result + marks;
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (Subject == null) {
            if (other.Subject != null)
                return false;
        } else if (!Subject.equals(other.Subject))
            return false;
        if (id != other.id)
            return false;
        if (marks != other.marks)
            return false;
        return true;
    }


}

在 Hashmap 中输入重复项以检查重写 equals 和 hashcode() 是否有效:

public class TestHashSet3 {

    static Student s1;
    static Student s2;
    static Student s3;

    public static void main(String[] args) {
        setStudent();
        testSet();
        testMap();
 }

    static void testMap() {
        Map<Student, String> empMap = new HashMap<>();
        empMap.put(s1, "Arun");
        empMap.put(s2, "Shivam");
        empMap.put(s3, "Varun");
        System.out.println("HashMap executed = ");
        for (Map.Entry<Student, String> obj : empMap.entrySet()) {
            System.out.println(obj  +  " ");
        }
    }

    static void testSet() {
        Set<Student> set = new HashSet<>();
        set.add(s1);
        set.add(s2);
        set.add(s3);
        System.out.println("HashSet executed = ");
        for (Student student : set) {
            System.out.println(student  +  " ");
        }

    }

    static void setStudent() {
        s1 = new Student(124, "Maths", 50);
        s2 = new Student(124, "Maths", 50);
        s3 = new Student(124, "Maths", 50);
    }
}

enter image description here enter image description here enter image description here enter image description here

在上一张截图中,我们可以看到这个 ==obj 结果是 false。但为什么呢?

最佳答案

嗯,hashCode() 并不总是返回内存地址。在您的具体情况下,您将覆盖该函数以基本上返回 Subject 引用的 hashCode。

您的评估显示以下输出:

stringops.Student@955a0720

这可能有点令人困惑,因为这实际上不是裸内存地址,而是对对象的 toString() 方法的调用。

Have a look at how Java implements toString:

getClass().getName() + '@' + Integer.toHexString(hashCode())

因此,事实上,这两个对象具有不同的内存位置,但由于您覆盖了 hashCode(),因此您将看不到它们。另外,没有办法覆盖 Java 选择对象内存地址的方式(可能除了一些 hack),但尽管如此,两个对象不能具有相同的地址。

下次请添加更多文字而不是屏幕截图,以提高其他人对您的问题的搜索能力。

关于java - Java检查内存地址中==运算符的作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54497634/

相关文章:

java - 如何从 map 对象获取列表值

arrays - Kotlin:字符串到键值的数组

java - 使用 "Boolean equals()"比较 ArrayList 中保存的对象

java - 从 Android 应用程序发送 OSC(开放式声音控制)消息

java - 当类扩展另一个类时如何使用枚举强制单例模式

java - 使用 Select Case 进行 JPA 条件查询

java - HashMap中的桶数是什么意思?

java - "null"String .equals( "null") 返回 false java (JOptionPane)

java - 断言集合包含自定义类的对象,它不会覆盖 equals/hashcode

java - 消费者线程等待多个队列