您的位置:首页 > 其它

HashMap实现原理及源码分析

2015-04-11 20:16 671 查看

1、数据结构

在数据结构与算法中,给我们介绍了常用的几种数据结构:数组,链表,哈希表。

数组结构:其在内存分配是一段连续的内存空间,可能会占用内存空间严重,空间复杂度很大,时间复杂度小,其优点是易于寻址,但是插入、删除困难。

链表结构:其在内存分配是一系列离散的内存空间,占用内存少,空间复杂度很小,时间复杂度很大,其优点是易于插入和删除,寻址困难。

哈希表:哈希表是集合数组和链表的存储结构,满足寻址方便,易于操作,占用内存空间较小,时间复杂度有较小。其例如下:



已知一组数据{19,14,23,01,68,20,84,27,55,11,10,79},按照哈希函数H(key)= key MOD 13和链表地址法处理哈希冲突,其哈希表如下:



上述是一个长度为13的数组,每个元素存储的是一个链表的头结点,用过Hash函数hash(key)%len获取索引位置。

2、HashMap的定义

HashMap的内部是按哈希表实现:



其定义源码如下(JDK1.8中对HashMap进行了很大的修改):

定义数组,存储Node节点。

<span style="font-size:14px;"> /**
     * The table, initialized on first use, and resized as
     * necessary. When allocated, length is always a power of two.
     * (We also tolerate length zero in some operations to allow
     * bootstrapping mechanics that are currently not needed.)
     */
    transient Node<K,V>[] table;</span>


Node节点实现Map.Entry接口,包含key,value,next,hash值。

<span style="font-size:14px;">/**
     * Basic hash bin node, used for most entries.  (See below for
     * TreeNode subclass, and in LinkedHashMap for its Entry subclass.)
     */
    static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        V value;
        Node<K,V> next;

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

        public final K getKey()        { return key; }
        public final V getValue()      { return value; }
        public final String toString() { return key + "=" + value; }

        public final int hashCode() {
            return Objects.hashCode(key) ^ Objects.hashCode(value);
        }

        public final V setValue(V newValue) {
            V oldValue = value;
            value = newValue;
            return oldValue;
        }

        public final boolean equals(Object o) {
            if (o == this)
                return true;
            if (o instanceof Map.Entry) {
                Map.Entry<?,?> e = (Map.Entry<?,?>)o;
                if (Objects.equals(key, e.getKey()) &&
                    Objects.equals(value, e.getValue()))
                    return true;
            }
            return false;
        }
    }</span>


其中Map.Entry接口如下:



3、HashMap的关键属性

HashMap的最主要的连个属性是默认初始大小和加载因子。

DEFAULT_LOAD_FACTOR = 0.75f; //默认table大小

DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 当大于默认大小时,调整大小增量
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: