Mrinal Sharma
Mrinal Sharma

Reputation: 1

Hashmap<key, value> have same inputs and equals and hashcode method implemented, but i am not getting error as duplicate key?

I have a very basic sample code to implement equals and hashcode.

There is one map in which object of Employee class is used as key. I have debugged the code, and equals method returning true for duplicate object. All the values are same for emp obj but I am not getting any error.

Could anybody help me to understand this behavior ??

Below is code I have:

import java.util.HashMap;
import java.util.Map;

class Employee {
private int empId;
private String name;

    public Employee(int empId, String name)
    {
        this.empId = empId;
        this.name = name;
    }

    @Override public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + empId;
        result = prime * result +
          ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override public boolean equals(Object obj)
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Employee other = (Employee)obj;
        if (empId != other.empId)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
}

class Address {
private int houseNo;
private String streetName;
private String city;
private int pinCode;

    public Address(int houseNo, String streetName, 
                        String city, int pinCode)
    {
        this.houseNo = houseNo;
        this.streetName = streetName;
        this.city = city;
        this.pinCode = pinCode;
    }

    public String getAddress()
    {
        return houseNo + ", " + streetName + ", " + 
                              city + ", " + pinCode;
    }

}

public class Test {
    public static String getAddress(Map map, Employee emp)
    {
        Address adrs = (Address)map.get(emp);
        return adrs.getAddress();
    }
    public static void main(String[] args)
    {
        Employee emp1 = new Employee(110, "Sajid Ali Khan");
        Address adrs1 = new Address(304, "Marol Mahrisi",
                                       "Mumbai", 400069);

        Employee emp2 = new Employee(111, "Jaspreet Singh");
        Address adrs2 = new Address(203, "Seepz", "Mumbai",
                                                  400093);

        Map<Employee, Address> map = new HashMap<>();
        map.put(emp1, adrs1);
        map.put(emp2, adrs2);
        //duplicate entry in map
        map.put(emp1, adrs1);

        System.out.println(Test.getAddress(map, new Employee(110, 
                                              "Sajid Ali Khan")));
    }
}

I have this also:

Employee emp3 = new Employee(111, "Jaspreet Singh");
Address adrs3 = new Address(203, "Seepz", "Mumbai", 400093);

and

map.put(emp1, adrs1);
map.put(emp2, adrs2);
map.put(emp1, adrs1);
map.put(emp2, adrs2);
map.put(emp3, adrs3);

  System.out.println("key in map: "+map.entrySet() );

but i am getting output as:

Size of map: [Employee@37889908=Address@3ad6a0e0, Employee@b9d91e41=Address@60dbf04d]
304, Marol Mahrisi, Mumbai, 400069

Upvotes: 0

Views: 130

Answers (2)

Prashant Patil
Prashant Patil

Reputation: 371

If you see the internal working of put method of HashMap.

public V put(K key, V value) 
{
    if (key == null)
       return putForNullKey(value);
    int hash = hash(key.hashCode());
    int i = indexFor(hash, table.length);
    for (Entry<K,V> e = table[i]; e != null; e = e.next) 
    {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) 
         {
             V oldValue = e.value;
             e.value = value;
             e.recordAccess(this);
             return oldValue;
          }
     }
     modCount++;
     addEntry(hash, key, value, i);
     return null;
 }

HashMap uses Hashing mechanism for assigning unique code to a variable or attribute using an algorithm to enable easy retrieval. A true hashing mechanism should always return the same hashCode() when it is applied to the same object.

As we all know, HashMap doesn't allow duplicate keys, even though when we insert the same key with different values, only the latest value is returned. Lets take example:

import java.util.HashMap;
import java.util.Map;
public class HashMapEg 
{
    public static void main(String[] args) 
        {
            Map map = new HashMap();
            map.put(1,"sam");   
            map.put(1,"Ian");   
            map.put(1,"Scott");   
            map.put(null,"asdf");
            System.out.println(map);  
        }
}

For the above code, you will get the output as {null=asdf, 1=Scott} , as the values sam and Ian will be replaced by Scott. So, how does this happen?

All the Entry Objects in the LinkedList will have the same hashcode, but HashMap uses equals() . This method checks the equality, so if key.equals(k) is true, then it will replace the value object inside the Entry class and not the key. So this way it prevents the duplicate key from being inserted.

For more details refer link1 and link2

I hope this will help you.

Upvotes: 1

Yogesh
Yogesh

Reputation: 4784

map.put method by default does not throw error it just replaces the value for that key. Checkout the javadoc

Upvotes: 2

Related Questions