Java HashMap源码小结

来源:互联网 发布:冷暴力孩子知乎 编辑:程序博客网 时间:2024/05/16 12:50

本文基于jdk1.8.

HashMap即哈希表,是一种能以常数平均时间完成插入,删除和查找操作的数据结构;

哈希表有两种实现方式:开放地址方式和冲突链表方式;开放地址方式不需要使用链表,但是要频繁的再散列操作,常用的再散列方法有线性探测法,平方探测法,双散列法。冲突链表方式将所有哈希值相同的键用链表串起来,理想情况下的哈希表每个哈希值对应一个键,此时查找操作为常数时间;

有两个参数与哈希表的性能有关:容量Capacity和装载因子load_factor,Threshold=Capacity * load_factor;

哈希表默认的容量是2^4;最大容量是2^30;装载因子默认为0.75;

当装入哈希表的元素大于threshold时,哈希表自动扩容,容量变为原来2倍,扩容后元素顺序会被打散,在不同时间遍历哈希表得到的结果可能不同;

在jdk1.8中,链表过长的话(长度>8),HashMap会将冲突链表转化为红黑树;

public class HashMap<K,V> extends AbstractMap<K,V>    implements Map<K,V>, Cloneable, Serializable

其底层实现是由数组和链表构造而成,如图:


1. get(Object key)

public V get(Object key) {        Node<K,V> e;        return (e = getNode(hash(key), key)) == null ? null : e.value;    }
通过传入key得到value;

2. getNode(int hash, Object key)

final Node<K,V> getNode(int hash, Object key) {        Node<K,V>[] tab; Node<K,V> first, e; int n; K k;        if ((tab = table) != null && (n = tab.length) > 0 &&            (first = tab[(n - 1) & hash]) != null) {            if (first.hash == hash && // always check first node                ((k = first.key) == key || (key != null && key.equals(k))))                return first;            if ((e = first.next) != null) {                if (first instanceof TreeNode)                    return ((TreeNode<K,V>)first).getTreeNode(hash, key);                do {                    if (e.hash == hash &&                        ((k = e.key) == key || (key != null && key.equals(k))))                        return e;                } while ((e = e.next) != null);            }        }        return null;    }
tab[n-1]&hash是确定key在哈希表中的位置;

然后在链表中寻找(k==key || key.equals(k)),找k是否==key或equals key;返回Node;

若需要将自定义的对象放入HashMap中,需要override equals方法和hashCode方法;
3. containsKey(Object key)

public boolean containsKey(Object key) {        return getNode(hash(key), key) != null;    }
判断哈希表中是否存在这个key;

4. put

public V put(K key, V value) {        return putVal(hash(key), key, value, false, true);    }
将一个键值对插入哈希表;

5.remove

public V remove(Object key) {        Node<K,V> e;        return (e = removeNode(hash(key), key, null, false, true)) == null ?            null : e.value;    }
将key对应的Node从哈希表中删除;


和其他集合类的比较:HashSet采用了适配器模式(HashSet里有一个HashMap);HashMap没有实现同步,HashTable实现了同步,其余类似;HashMap元素无序,TreeMap元素有序;

参考文章:https://zhuanlan.zhihu.com/p/24828513


0 0
原创粉丝点击