Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HashMap in Java

Tags:

java

hashmap

I had an interview today, and I got the following Java code:

public class Question_6 {
    public static void main(String[] args){
        Map<Integer,String> map1 = new HashMap<Integer,String>();
        map1.put(new Integer(1),"001a");
        map1.put(new Integer(1),"001b");
        map1.put(new Integer(2),"002");

        System.out.println(map1.size());

        Map<MyInt,String> map2 = new HashMap<MyInt,String>();
        map2.put(new MyInt(1),"001a");
        map2.put(new MyInt(1),"001b");
        map2.put(new MyInt(2),"002");

        System.out.println(map2.size());

    }

}
public class MyInt {
    int i;
    public MyInt(int i) {
       this.i = i;
    }

}

The questions were:

  1. What will be printed to the console?

  2. Suggest a solution to the problem.

I know now that the answer to the first question is :

2

3

But I don't know why? What is the problem with MyInt?

like image 305
Moosh Avatar asked May 29 '13 16:05

Moosh


4 Answers

Your problem is that equals() and hashcode() is not implemented on MyInt.

You are expected to have 2 as a result in both cases.

HashMap, as the name implies, groups the keys into buckets based on the keys' hashcode(). But the default hashcode does not match for two instances of MyInt with the same value.

To determine equality, you have to override equals() as well.

One solution:

public class MyInt {

    [...]

    @Override
    public int hashCode() {
       return value;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof MyInt) {
            return i == ((MyInt)obj).i;
        }
        return false;
    }

}
like image 127
gaborsch Avatar answered Sep 21 '22 06:09

gaborsch


You need to override the equals() and hashCode() method in your MyInt class , so that HashMap can comprehend new MyInt(1).equals(new MyInt(1)) is true.

like image 26
AllTooSir Avatar answered Sep 23 '22 06:09

AllTooSir


The Integer class overrides the equals() method to do value based comparison. Hashmaps cannot contain two keys that are "equal", so the 2nd insertion into map1 will overwrite the first entry. As well, the hashcode() method is overridden.

However, MyInt does not override the equals() or hashcode() method so equality is memory location based. Therefore, map2 sees three distinct keys and makes three distinct entries.

    Map<MyInt,String> map2 = new HashMap<MyInt,String>();
    MyInt one = new MyInt(1);
    MyInt two = new MyInt(2);
    map2.put(one,"001a");
    map2.put(one,"001b");
    map2.put(two,"002");

    System.out.println(map2.size());

Produces an output of 2 in this case because one.equals(one) is true in this case.

like image 25
waldol1 Avatar answered Sep 21 '22 06:09

waldol1


map1.put(new Integer(1),"001a");
        map1.put(new Integer(1),"001b");//same location in map
        map1.put(new Integer(2),"002");

in this part you use the Integer class, Integer class don't allow setting the same location, but your Integer class allow.

Change code like this, and you see the problem

public class Question_6 {
    public static void main(String[] args){
        Map<Integer,String> map1 = new HashMap<Integer,String>();
        map1.put(new Integer(1),"001a");
        map1.put(new Integer(2),"001b");
        map1.put(new Integer(3),"002");

        System.out.println(map1.size());

        Map<MyInt,String> map2 = new HashMap<MyInt,String>();
        map2.put(new MyInt(1),"001a");
        map2.put(new MyInt(2),"001b");
        map2.put(new MyInt(3),"002");

        System.out.println(map2.size());

    }

this code will print ;

3 3

So, your Integer class(myInt) is true but missing

like image 45
oguzhancerit Avatar answered Sep 21 '22 06:09

oguzhancerit