我们一直知道HashMap是非线程安全的,HashTable是线程安全的,可这是为什么呢?先聊聊HashMap吧,想要了解它为什么是非线程安全的,我们得从它的原理着手。

jdk7中的HashMap

HashMap底层维护一个数组,数组中的每一项都是Entry

transient Entry<K,V>[] table;

我们向HashMap放置的对象实际上是放置在Entry数组中

而Map中的key、value则以Entry的形式存放在数组中

private static class Entry<K,V> implements Map.Entry<K,V> {    final int hash;    final K key;
    V value;    Entry<K,V> next;

而这个Entry应该放在数组的哪一个位置上(这个位置通常称为位桶或者hash桶,即hash值相同的Entry会放在同一位置,用链表相连),是通过key的hashCode来计算的。

iOS培训,Swift培训,苹果开发培训,移动开发培训

当两个key通过hashcode计算是相同的时候,就会发生hash冲突,HashMap解决hash冲突的办法是使用链表。

简而言之就是,如果该位置没有对象,则将对象直接放到数组中,如果该位置有对象,顺着存在此对象的链找(Map中不允许存在相同的key和value),如果不存在相同的,第一种情况:如果该链表扩容了,则把对象放入到数组中,原先存放在数组中的数据放置该对象的后面。第二种情况:如果该链表没有扩容,则直接放到链表的最后。如果存在相同的,则进行替换。

网友评论