-3

I have written a code which has Student class and student objects are used as keys as follows,

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

In the above code in Student class the hashcode and equals are implemented as follows,

@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;
    }

Now when I compile and run the code,

the code in method example02 gives an output as

HASHCODE 372, ID 12, NAME Arnold

i.e the Set holds only one object,

What I understood that as the key of all the objects has the same hashcode hence only single object lies in the bucket 372. Am I right ?

Also the method example03() give output as

Key : [ HASHCODE 372, ID 12, NAME Arnold ], Value : [ 2 ] 

From the above method we can see that as the key returns the same hashcode, the Hashmap only holds the single key value pair.

So my question is where does the collision happens ?

Can a key can point to multiple values ?

Where does the linkedlist concept comes while searching for value of respective key ?

Can anybody please explain me the above things with respect to the examples I have shared ?

haMzox
  • 2,073
  • 1
  • 12
  • 25
Rahul Shivsharan
  • 2,481
  • 7
  • 40
  • 59
  • 2
    Hash collision is not a problem, your problem is the fact that you provide equal IDs and you only check that in your `equals` method. – Tom Jun 15 '17 at 10:50

1 Answers1

1

What is hashmap collisioning ?

There is no such thing as "hashmap collision".

There is such a thing as "hashcode collision". That happens when two objects have the same hashcode, but are not equal.

Hashcode collision is not a problem ... unless it happens frequently. A properly designed hash table data structure (including HashMap or HashSet) will cope with collision, though if the probability of collision is too high, performance will tend to suffer.


Does [hashcode collision] occur in my code?

No.

The problems with your code are not due hashcode collision:

  • Your equals method is in effect saying that two Student objects are equal if-and-only-if they have the same hashcode. Since your hashcode is computed from only the ID, this means that any Student objects with the same ID are equal by definition.

  • Then you add lots of Student objects that have the same ID (12) and different names. Obviously, that means they are equal. And that means that the HashSet will only hold one of them ... at any given time.


So my question is where does the collision happens ?

The problem is that the Student objects are all equal.

Can a key can point to multiple values ?

This is a HashSet not a HashMap. There are no "keys". A Set is a set of unique values ... where unique means that the members are not equal.

Where does the linkedlist concept comes while searching for value of respective key ?

If you are talking about the LinkedList class, it doesn't come into it.

If you are talking about linked lists in general, the implementation of HashSet can use a form of linked list to represent the hash chains. But that is an implementation detail, and not something that makes any difference to your example.

(If you really want to know how HashSet works use Google to search for "java.util.HashSet source" and read the source code. Note that the implementations are different in different versions of Java.)


Can a key can point to multiple values ?

No. The Map API doesn't support that.

But of course you could use a map like this:

Map<Key, List<Value>> myMultimap = .....
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Thanks for for your reply. It was very helpful. My second question was whether in hashmap a key can be mapped to multiple values ?. And my question regarding linkedlist was, while fetching the value accross each key in hashmap a linkedlist datastructure is used. is it true ? if yes that how it works, can you explain me ? – Rahul Shivsharan Jun 16 '17 at 04:58
  • *"And my question regarding linkedlist was, while fetching the value accross each key in hashmap a linkedlist datastructure is used. is it true ? if yes that how it works, can you explain me ?"* - I answered both of those. My answer was **read the source code** ... because it is too complicated to explain properly in a StackOverflow Answer. – Stephen C Jun 16 '17 at 08:22
  • @RahulShivsharan related: https://stackoverflow.com/questions/44031592/will-similar-strings-in-hashmap-lead-to-increased-chance-of-collisions/44046106#44046106 and https://stackoverflow.com/questions/43911369/hashmap-java-8-implementation/43924719#43924719 – Eugene Jun 16 '17 at 08:58