Map HashCode and Equals



我正在尝试检索HashMap中覆盖equals和hashcode方法的另一个元素的值。当我为student1和student3使用相同的哈希代码,并且这两个对象相等时,为什么rollId返回null?理想情况下,它应该给我3英镑。以下是代码片段:

主要类别

public static void main(String[] args) {
    Map<Student, Integer> studentMap = new HashMap<Student, Integer>();
    Student student1 = new Student();
    student1.setRollId(1);
    Student student2 = new Student();
    student2.setRollId(2);
    studentMap.put(student1, 1);
    studentMap.put(student2, 2);
    for (Entry<Student, Integer> entry : studentMap.entrySet()) {
        if (entry.getValue().equals(1)) {
            student1.setRollId(3);
        }
    }
    Student student3 = new Student();
    student3.setRollId(3);
    System.out.println("Student1 HashCode " + student1.hashCode()
            + " Student3 HashCode " + student3.hashCode());
    System.out.println("Object Equal === > " + student1.equals(student3));
    Integer rollId = studentMap.get(student3);
    System.out.println("RollId is " + rollId);
}


学生班

private Integer rollId;
public Integer getRollId() {
    return rollId;
}
public void setRollId(Integer rollId) {
    this.rollId = rollId;
}
@Override
public int hashCode() {
    return rollId;
}
@Override
public boolean equals(Object obj) {
    Student student = (Student)obj;
    if(this.rollId.equals(student.getRollId()))
    {
        return true;
    }
    return false;
}

HashMap最终将键值对存储在表中,并使用给定键的哈希码计算表中映射值的索引。

当您修改rollId属性时,您还将修改键的哈希代码,这反过来会导致在内部表中查找与映射最初用于存储值的索引不同的索引。

例如,该表最初可能被分配了特定的容量16,并且这两个对条目被存储在索引1和2处(给定在Student对象中设置的rollId)。将哈希键从1更改为3后,映射将进行搜索不存储任何值的索引3。

在将散列键放入映射后,不能更改散列键并期望映射继续正常工作。如果要更改密钥,则必须删除该项目,更改密钥,然后重新插入。

来自Java文档:

注意:如果使用可变对象作为映射键,则必须格外小心。当对象是映射中的键时,如果对象的值以影响相等比较的方式更改,则不会指定映射的行为。

代码的问题是没有向studentMap添加任何值。此外,我不明白为什么要对RollId使用Integer,并从中为hashCode计算int。如果您确实需要Integer来获得更大的范围,那么32位的hashcode(如您所计算的)可能会为不同的rollIds产生重复。考虑更改为int/

试试这个代码:

StudentDriver类

package com.example.student;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class StudentDriver {
    private static Student student1, student2, student3;
    public static void main(String[] args) {
        Map<Student, Integer> studentMap = new HashMap<Student, Integer>();
        student1 = new Student();
        student2 = new Student();
        student1.setRollId(1);
        student2.setRollId(2);
        studentMap.put(student1, student1.getRollId());
        studentMap.put(student2, student2.getRollId());
        for (Entry<Student, Integer> entry : studentMap.entrySet()) {
            System.out.println("Entry information: " + entry.getValue());
            if (entry.getValue().equals(1)) {
                student1.setRollId(3);
            }
        }
        student3 = new Student();
        student3.setRollId(3);
        System.out.println("Student1 Hashcode = " + student1.hashCode()
                          +", Student3 Hashcode = " + student3.hashCode()) ;  
        System.out.println("Object equal ==> " + student1.equals(student3));
        Integer rollId = student3.getRollId();
        System.out.println("RollId is " + rollId);
    }
}

学生班

package com.example.student;
public class Student {
    // Object fields
    private Integer rollId;
    public Integer getRollId() {
        return rollId;
    }
    public Student setRollId(Integer rollId) {
        this.rollId = rollId;
        return this;
    }
    @Override
    public int hashCode() {
        return rollId.intValue();
    }
    @Override
    public boolean equals(Object other) {
        return other instanceof Student && ((Student)other).getRollId() == rollId;
    }
}

最新更新