HashMap源代码

原创 2016年05月30日 20:21:19

HashMap是最常使用的类,所以学习它的源码很重要。

HashMap的结构如下:


/**
     * The table, resized as necessary. Length MUST Always be a power of two.
     */
    transient Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE;

由Entry[] table负责存储数据。其中Entry是它的静态内部类,Entry结构如下:

static class Entry<K,V> implements Map.Entry<K,V> {
        final K key;
        V value;
        Entry<K,V> next;
        int hash;
很明显可以看出,Entry就是一个链表,所以HashMap的结构其实就是一个数组,然后数组里面的元素是链表,如下图所示:


HashMap中最常使用的方法是get和put,首先看下put方法

public V put(K key, V value) {
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
        if (key == null)//允许null key
            return putForNullKey(value);
        int hash = hash(key);//对key进行hash
        int i = indexFor(hash, table.length);//通过hash值找到对应存储位置
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {//遍历链元素,查找链表中有没有相同的key,如果有就替换
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {//先比较hash,如果hash值相等,再比较具体的key值
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);//如果没有key,就做插入
        return null;
    }

private V putForNullKey(V value) {
        for (Entry<K,V> e = table[0]; e != null; e = e.next) {//大体过程与普通put操作一样,只不过要注意如果是null key就存储在0位置
            if (e.key == null) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }
        modCount++;
        addEntry(0, null, value, 0);
        return null;
    }

get方法:

public V get(Object key) {
        if (key == null)
            return getForNullKey();
        Entry<K,V> entry = getEntry(key);

        return null == entry ? null : entry.getValue();
    }
private V getForNullKey() {
        if (size == 0) {
            return null;
        }
        for (Entry<K,V> e = table[0]; e != null; e = e.next) {//没什么好说的,就要注意null key的值存储在0位置
            if (e.key == null)
                return e.value;
        }
        return null;
    }
final Entry<K,V> getEntry(Object key) {
        if (size == 0) {
            return null;
        }

        int hash = (key == null) ? 0 : hash(key);//再次证明null key 在0位置
        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 != null && key.equals(k))))
                return e;
        }
        return null;
    }






版权声明:本文为博主原创文章,未经博主允许不得转载。

HashMap的两中迭代方式(源代码解析)

Map map = new HashMap(); map.put("a1", "a11"); map.put("a2", "a22"); Set set = map.keySet(); for...

共同学习Java源代码-数据结构-HashMap(十六)

final TreeNode find(int h, Object k, Class kc) {             TreeNode p = this;             do {    ...
  • ccdust
  • ccdust
  • 2017年11月30日 16:46
  • 17

HashMap源代码分析

HashMap是java中常用的集合类,它用于

通过 HashMap、HashSet 的源代码分析其 Hash 存储机制

实际上,HashSet 和 HashMap 之间有很多相似之处,对于 HashSet 而言,系统采用 Hash 算法决定集合元素的存储位置,这样可以保证能快速存、取集合元素;对于 HashMap 而言...
  • Hsuxu
  • Hsuxu
  • 2012年04月12日 16:10
  • 800

Java HashMap源代码详解

package java.util; import java.io.*; public class HashMap extends AbstractMap implements Ma...
  • ldrmcml
  • ldrmcml
  • 2014年10月09日 19:40
  • 426

共同学习Java源代码-数据结构-HashMap(十九)

final void split(HashMap map, Node[] tab, int index, int bit) {             TreeNode b = this;    ...
  • ccdust
  • ccdust
  • 2017年12月06日 15:30
  • 19

JDK HashMap源代码分析

文章来自下面的网址: http://www.360doc.com/content/10/1214/22/573136_78200435.shtml 1.    Ha...

HashMap源代码详解

HashMap是键值对的集合,其中键不重复并且可以为空,值也可以为空。HaspMap的存取效率非常高,可以在O(1)时间内实现存取操作。HaspMap的实现是线程非安全的,所以在多线程环境下会有并发问...

共同学习Java源代码-数据结构-HashMap(十八)

final TreeNode putTreeVal(HashMap map, Node[] tab,                                        int h, K k...
  • ccdust
  • ccdust
  • 2017年12月05日 19:47
  • 17

依然思路之hashmap源代码

第一:看一个源代码先看继承的父类,实现了那些接口 HashMap 实现了Serializable接口,因此它支持序列化,实现了Cloneable接口,能被克隆。 第二:看定义的变量   // ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HashMap源代码
举报原因:
原因补充:

(最多只允许输入30个字)