4

Cobnsider the following code:

public static void main (String[] args) {
    Map<Number, String> map = new HashMap<Number, String>();
    map.put(1L, "test");
    System.out.println(map.get(1));
}

Why HashMap.get returns null? O_o It must return value for any object which hashCode function returns 1, is not it?

UPDATED

The problem is Map interface receives Object, not parameterized type. So I expected that any object can be a key, but HashMap implementation check type with equals, it was surprising for me.

And autoboxing is not the problem. I know, that 1 became Integer, and 1L to Long. But they have same hashcode. So as I thought any implementation Map#get should return value for any Object with same hashcode.

2
  • 3
    Try System.out.println(map.get(1L)); Commented Oct 22, 2013 at 7:55
  • You are right that Integer 1 and Long 1L have the same hash code and would be stored in the same bucket inside the map. But then .equals is done and returns false. Commented Nov 15, 2017 at 10:28

5 Answers 5

6

You're putting a key of 1L (Long) and getting a key of 1 (Integer).

They're not the same thing, so be careful.

Either remove the L from the put, or add the L to the get. Or even better, don't write them out as primitives and rely on autoboxing.

Sign up to request clarification or add additional context in comments.

2 Comments

Or do not use HashMap<Number, String> but HashMap<Long, String> instead
@TwoThe Indeed, I didn't even pay attention to that.
1

It's because you're not passing a Long type of key when retrieving the value, but an integer instead. These get autoboxed as different objects and therefore do not represent the same key.

Comments

1

Integers and Longs are not the same.

Integer#equals

public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}

Long#equals

public boolean equals(Object obj) {
    if (obj instanceof Long) {
        return value == ((Long)obj).longValue();
    }
    return false;
}

Comments

1

There is a type mismatch between putting and getting.

What happens here is AutoBoxing, Java will perform conversion between primitives to its Object equivalents and vice-versa for you automatically rather than via the new(), So became Integer and another is Long.

Try the below ways:

public static void main (String[] args) {
        Map<Number, String> map = new HashMap<Number, String>();
        map.put(1L, "test");
        System.out.println(map.get(1L));
    }

Or

public static void main (String[] args) {
        Map<Number, String> map = new HashMap<Number, String>();
        map.put(1, "test");
        System.out.println(map.get(1));
    }

Though both have same value(1) but of different objects they are not equal,

i.e. Integer(1) != Long(1).

That is the problem here, which is being happened by using Auto-boxing.

A quick example

        Long l = new Long(1);
        Integer i = new Integer(1);
        System.out.println(i.equals(l)); //false -->Hashmap get() failed here
        System.out.println(i.intValue() ==l.intValue());//true

Comments

-2

I spot the problem, see java.util.HashMap#get source code, it contains:

public V get(Object key) {
        if (key == null)
            return getForNullKey();
        int hash = hash(key.hashCode());
        for (Entry<K,V> e = table[indexFor(hash, table.length)];
             e != null;
             e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
                return e.value;
        }
        return null;
    }

So it check key with equals before returning the value.

2 Comments

What is the problem with java.util.HashMap#get?
Actually your problem is not with get It meant as why equals fails ? That is because of Auto boxing :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.