Collision resolution in Java HashMap
Java HashMap
uses put
method to insert the K/V pair in HashMap
. Lets say I have used put
method and now HashMap<Integer, Integer>
has one entry with key
as 10 and value
as 17.
If I insert 10,20 in this HashMap
it simply replaces the the previous entry with this entry due to collision because of same key 10.
If the key collides HashMap
replaces the old K/V pair with the new K/V pair.
So my question is when does the HashMap
use Chaining collision resolution technique?
Why it did not form a linkedlist
with key as 10 and value as 17,20?
When you insert the pair (10, 17)
and then (10, 20)
, there is technically no collision involved. You are just replacing the old value with the new value for a given key 10
(since in both the cases, 10 is equal to 10 and also the hash code for 10 is always 10).
Collision happens when multiple keys hash to the same bucket. In that case, you need to make sure that you can distinguish between those keys. Chaining collision resolution is one of those techniques which is used for this.
As as example, let's suppose that two strings "abra ka dabra"
and "wave my wand"
yield hash codes 100
and 200
respectively. Assuming the total array size is 10, both of them end up in the same bucket ( 100 % 10
and 200 % 10
). Chaining ensures that whenever you do map.get( "abra ka dabra" );
, you end up with the correct value associated with the key. In the case of hash map in Java, this is done by using the equals
method.
In an HashMap
the key is an object, that contains hashCode()
and equals(Object)
methods.
When you insert a new entry on the Map, it checks whether the hashCode
is already known. Then, it will iterate through all objects with this hashcode, and test their equality with .equals()
. If an equal object is found, the new value replace the old one. If not, it will create a new entry in the map.
Usually, talking about maps, you use collision when two objects have the same hashCode
but they are different. They are internally stored in a list.
It could have formed a linked list, indeed. It's just that Map
contract requires it to replace the entry:
V put(K key, V value)
Associates the specified value with the specified key in this map (optional operation). If the map previously contained a mapping for the key, the old value is replaced by the specified value. (A map m is said to contain a mapping for a key k if and only if m.containsKey(k) would return true.)
http://docs.oracle.com/javase/6/docs/api/java/util/Map.html
For a map to store lists of values, it'd need to be a Multimap
. Here's Google's: http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Multimap.html
A collection similar to a Map, but which may associate multiple values with a single key. If you call put(K, V) twice, with the same key but different values, the multimap contains mappings from the key to both values.
Edit: Collision resolution
That's a bit different. A collision happens when two different keys happen to have the same hash code, or two keys with different hash codes happen to map into the same bucket in the underlying array.
Consider HashMap
's source (bits and pieces removed):
public V put(K key, V value) {
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
// i is the index where we want to insert the new element
addEntry(hash, key, value, i);
return null;
}
void addEntry(int hash, K key, V value, int bucketIndex) {
// take the entry that's already in that bucket
Entry<K,V> e = table[bucketIndex];
// and create a new one that points to the old one = linked list
table[bucketIndex] = new Entry<>(hash, key, value, e);
}
For those who are curious how the Entry
class in HashMap
comes to behave like a list, it turns out that HashMap
defines its own static Entry
class which implements Map.Entry
. You can see for yourself by viewing the source code:
GrepCode for HashMap
链接地址: http://www.djcxy.com/p/92196.html上一篇: 为什么LinkedHashMap类实现Map接口?
下一篇: Java HashMap中的冲突解决方案