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

时间:2019-02-02 21:20:10

标签: java hashmap equals hashcode

直到今天我有一个信念,即两个对象具有相同的散列码装置两者具有相同的存储器位置。但是下面的代码总共讲述了一个不同的故事:

学生实体: 公共类学生器具可比{

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&哈希码()如下:

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。但是为什么呢?

3 个答案:

答案 0 :(得分:2)

好吧,hashCode()总是返回内存地址并不完全正确。在您的特定情况下,您将覆盖该函数以基本上返回Subject引用的hashCode。

您的评估显示以下输出:

stringops.Student@955a0720

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

Have a look at how Java implements toString

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

因此,实际上,这两个对象具有不同的存储位置,但是由于覆盖了hashCode(),因此看不到它们。而且,没有办法覆盖Java如何选择对象的内存地址(也许有些黑客除外),但是,两个对象不能具有相同的地址。

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

答案 1 :(得分:1)

hashcode是由hascode()方法返回的int值。

Object.java定义hascode()和每一Java类是子类Object.java的,因此每个类继承它。

如果特定类的开发者希望重写它,则由他/她决定。一类的开发人员可以选择(虽然一种不好的做法),以用于一个类的所有对象retrun相同恒定int值。

通常,hascode取决于对象的一个​​或多个属性的值。即使开发人员可能会尽力返回唯一的哈希码,但是(哈希码冲突)两个不同的对象可能最终会返回相同的hascode。

一次只能将一个内存位置分配给一个对象。

两个不同对象(位于内存中两个不同地址)的哈希码可能相同或不同

还有一个相关概念:等号合约和hascode方法。它说如果两个对象通过调用equals返回true,则两个对象必须具有相同的哈希码。请注意,这是定义的合同,但是开发人员可以开发类并编写哈希码方法以遵守合同。错误的实现可能导致两个对象返回不同的hascodes,而equals方法返回true。

答案 2 :(得分:1)

您已经正确地确定了两个不同的对象(即,两个不在同一内存地址的对象)确实可以具有相同的哈希码。的规则是,如果两个对象由.equals()方法相等,那么它们应产生相同的散列码。除此以外,还有一个普遍的想法,即“不同的对象应尝试使用不同的哈希码”,但不要求位于不同位置的对象应进行不同的哈希处理。

这是一件好事。例如,每个具有相同字符序列的两个不同的String对象应该直观地具有相同的哈希码,以便HashMap<String, T>可以正确地查找字符串。这样,提供与用作键的对象不同但具有相同逻辑值的String对象将可以正常工作;所有String S采用相同的字符序列的散列到相同的点。