HashMap源码分析(一)

161 阅读2分钟

HashMap结构

想了解HashMap先了解下Map这个结构,Map是key,value一一对应的一个链表散列结构。HashMap是在map的基础上通过hash算法来实现,目的是为了使key数组中的数据尽量分局均匀。 HashMap的key是通过数组和链表组成,数组来保存key,链表用来解决hash碰撞,当hash碰撞后把node放入链表中,通过next指向这个node。

为什么用HashMap

开发中不是所有数据都像List或者数组和链表一样,我们直接把一类数据都放进去就可以了,经常会碰到像上学时候的分数册一样的数据格式,他们是key,value来相互对应的所以用到了Map,而HashMap用Map这个数据结构进行封装和优化,更方便在开发中使用。

下面就来具体的看一下HashMap的代码

 Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

上面就是HashMap中一个node中所包含的数据,hash是通过对key进行hash操作后得出来的,next用来指向链表中的下一个节点。

 public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);
        this.loadFactor = loadFactor;
        this.threshold = tableSizeFor(initialCapacity);
    }

这一个就是hashmap真正做事情的构造方法,前面三个if都是为了的代码健壮性,第二个if目的是如果初始化的容量比最大容量还大就把初始化容量设置为最大容量,loadfactor是负载因子,默认是0.75,当空间使用到了0.75就开始扩容,至于为什么是0.75?简单说就是如果比0.75高就会当地空间开销但是查找成本提高,低于0.75则相反,所以使用0.75,具体细节可以查看这篇文章。threshold反应过来时阈值,理解成当前所能容纳的上限,它是通过tableSizeFor()这个方法使用初始化的容量计算出来的,上面就是HashMap在构造函数中做的所有的事情,这个初始化容量是可以自己设置的,如果保存的数据量比较大可以通过设置初始化容量来减少后面扩容来提高性能。

这一节就简单介绍下HashMap,后面会逐渐分析put,resize等。