Java 什么是hashmap冲突?它出现在我的代码中吗?

Java 什么是hashmap冲突?它出现在我的代码中吗?,java,hashmap,Java,Hashmap,我已经写了一个代码,其中有学生类和学生对象被用作键 如下: public class ExampleMain01 { private static class Student{ private int studentId; private String studentName; Student(int studentId,String studentName){ this.studentId = studentI

我已经写了一个代码,其中有学生类和学生对象被用作键 如下:

public class ExampleMain01 {

    private static class Student{
        private int studentId;
        private String studentName;

        Student(int studentId,String studentName){
            this.studentId = studentId;
            this.studentName = studentName;
        }

        @Override
        public int hashCode(){
            return this.studentId * 31;
        }

        @Override
        public boolean equals(Object obj){
            boolean flag = false;
            Student st = (Student) obj;


            if(st.hashCode() == this.hashCode()){
                flag = true;
            }

            return flag;
        }

        @Override
        public String toString(){
            StringBuffer strb = new StringBuffer();

            strb.append("HASHCODE ").append(this.hashCode())
            .append(", ID ").append(this.studentId)
            .append(", NAME ").append(this.studentName);

            return strb.toString();
        }

        public int getStudentId() {
            return studentId;
        }

        public String getStudentName() {
            return studentName;
        }
    } // end of class Student

    private static void example02() throws Exception{
        Set<Student> studentSet = new HashSet<Student>();
        studentSet.add(new Student(12, "Arnold"));
        studentSet.add(new Student(12, "Sam"));
        studentSet.add(new Student(12, "Jupiter"));
        studentSet.add(new Student(12, "Kaizam"));
        studentSet.add(new Student(12, "Leny"));

        for(Student s : studentSet){
            System.out.println(s);
        }
    } // end of method example02

    private static void example03() throws Exception{
        Map<Student, Integer> map = new HashMap<Student,Integer>();

        Student[] students = new Student [] {
            new Student(12, "Arnold"),
            new Student(12, "Jimmy"),
            new Student(12, "Dan"),
            new Student(12, "Kim"),
            new Student(12, "Ubzil")
        };


        map.put(students[0], new Integer(23));
        map.put(students[1], new Integer(123));
        map.put(students[2], new Integer(13));
        map.put(students[3], new Integer(25));
        map.put(students[4], new Integer(2));

        Set<Map.Entry<Student, Integer>> entrySet = map.entrySet();

        for(Iterator<Map.Entry<Student, Integer>> itr = entrySet.iterator(); itr.hasNext(); ){
        Map.Entry<Student, Integer> entry = itr.next();
        StringBuffer strb = new StringBuffer();

        strb.append("Key : [ ").append(entry.getKey()).append(" ], Value : [ ").append(entry.getValue()).append(" ] ");

           System.out.println(strb.toString());
        }

    } // end of method example03    

    public static void main(String[] args) {
        try{

            example02();
            example03();



        }catch(Exception e){
            e.printStackTrace();
        }

     }// end of main method

} // end of class ExampleMain01
@Override
    public int hashCode(){
        return this.studentId * 31;
    }

    @Override
    public boolean equals(Object obj){
        boolean flag = false;
        Student st = (Student) obj;         

        if(st.hashCode() == this.hashCode()){
            flag = true;
        }

        return flag;
    }
现在当我编译并运行代码时

方法example02中的代码给出了如下输出:

HASHCODE 372, ID 12, NAME Arnold
Key : [ HASHCODE 372, ID 12, NAME Arnold ], Value : [ 2 ] 
i、 e该集合仅容纳一个对象

我所理解的是,由于所有对象的键都具有相同的hashcode,因此bucket 372中只有一个对象。我说得对吗

方法example03()也将输出作为

HASHCODE 372, ID 12, NAME Arnold
Key : [ HASHCODE 372, ID 12, NAME Arnold ], Value : [ 2 ] 
从上面的方法可以看出,由于键返回相同的哈希代码, Hashmap只保存单个键值对

所以我的问题是碰撞发生在哪里

一个键可以指向多个值吗

在搜索各个键的值时,linkedlist的概念从何而来

有谁能就我分享的例子向我解释一下上述情况吗

什么是hashmap冲突

没有“hashmap冲突”这样的事情

有一件事叫做“哈希代码冲突”。当两个对象具有相同的哈希代码但不相等时,就会发生这种情况

哈希代码冲突不是问题。。。除非经常发生。适当设计的哈希表数据结构(包括
HashMap
HashSet
)将处理冲突,但如果冲突概率太高,性能往往会受到影响


我的代码中是否发生[hashcode冲突]

没有

代码中的问题不是由于哈希代码冲突造成的:

  • 您的
    equals
    方法实际上是说两个
    Student
    对象当且仅当它们具有相同的hashcode时才相等。由于hashcode仅从ID计算,这意味着任何具有相同ID的
    Student
    对象在定义上都是相等的

  • 然后添加许多具有相同ID(12)和不同名称的
    Student
    对象。显然,这意味着他们是平等的。这意味着
    HashSet
    将只保存其中一个。。。在任何给定的时间


所以我的问题是碰撞发生在哪里

问题是
Student
对象都是相等的

一个键可以指向多个值吗

这是一个
HashSet
而不是
HashMap
。没有“钥匙”。
集合
是一组唯一的值。。。其中“唯一”表示成员不相等

在搜索各个键的值时,linkedlist的概念从何而来

如果您谈论的是
LinkedList
类,那么它就不在其中

如果您一般谈论的是链表,
HashSet
的实现可以使用链表的形式来表示哈希链。但这是一个实现细节,而不是对您的示例有任何影响的东西

(如果您真的想知道
HashSet
的工作原理,请使用Google搜索“java.util.HashSet source”并阅读源代码。请注意,不同版本的java中的实现是不同的。)


一个键可以指向多个值吗

否。
Map
API不支持这一点

但你当然可以使用这样的地图:

Map<Key, List<Value>> myMultimap = .....
Map myMultimap=。。。。。

Hash冲突不是问题,您的问题是您提供了相等的ID,并且只在
equals
方法中检查。感谢您的回复。这很有帮助。我的第二个问题是,在hashmap中,一个键是否可以映射到多个值?。关于linkedlist,我的问题是,在获取hashmap中每个键的值时,使用的是linkedlist数据结构。这是真的吗?如果是,它是如何工作的,你能解释我吗?“我关于linkedlist的问题是,在获取hashmap中每个键的值时,使用了linkedlist数据结构。这是真的吗?如果是,它是如何工作的,你能解释我吗?”-我回答了这两个问题。我的答案是阅读源代码。。。因为它太复杂了,无法在StackOverflow答案中正确解释。@RahulShivsharan相关:和