**************start 此处摘自 <http://www.cnblogs.com/chengxiao/>************数组
简单来讲,HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的,若是定位到的数组位置不含链表(当前entry的next指向null),那么对于查找,添加等操做很快,仅需一次寻址便可;若是定位到的数组包含链表,对于添加操做,其时间复杂度为O(n),首先遍历链表,存在即覆盖,不然新增;对于查找操做来说,仍需遍历链表,而后经过key对象的equals方法逐一比对查找。因此,性能考虑,HashMap中的链表出现越少,性能才会越好。安全
*******end*********数据结构
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; return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; }
判断当前肯定的索引位置是否存在相同hashcode和相同key的元素,若是存在相同的hashcode和相同的key的元素,那么新值覆盖原来的旧值,并返回旧值。 若是存在相同的hashcode,那么他们肯定的索引位置就相同,这时判断他们的key是否相同,若是不相同,这时就是产生了hash冲突。 Hash冲突后,那么HashMap的单个bucket里存储的不是一个 Entry,而是一个 Entry 链。 系统只能必须按顺序遍历每一个 Entry,直到找到想搜索的 Entry 为止——若是刚好要搜索的 Entry 位于该 Entry 链的最末端(该 Entry 是最先放入该 bucket 中), 那系统必须循环到最后才能找到该元素。
*******ps:本人为新手只是记录本身的学习过程,若是有错误,但愿大神指出,共同窗习**************性能