HashMap和ConcurrentHashMap的区别:
Hashmap本质是数组加链表。根据key取得hash值,然后计算出数组下标,如果多个key对应到同一个下标,就用链表串起来,新插入的在前面。所以他不保证映射的顺序。
ConcurrentHashMap:在hashMap的基础上,ConcurrentHashMap将数据分为多个segment,默认16个(concurrency level),然后每次操作对一个segment加锁,避免多线程锁的几率,提高并发效率。
HashMap的底层源码:
一. 数据结构
Map将实际数据存储在Entry类的数组中。
transient Entry[] table; //HashMap的成员变量,存放数据
static class Entry<K,V> implements Map.Entry<K,V> { //内部类Entry
final K key;
V value;
Entry<K,V> next; //指向下一个数据
final int hash;
/**
* Creates new entry.
*/
Entry(int h, K k, V v, Entry<K,V> n) {
value = v;
next = n; //hash值冲突后存放在链表的下一个
key = k;
hash = h;
}
HashMap其实就是一个Entry数组,Entry对象中包含了键和值,其中next也是一个Entry对象,它就是用来处理hash冲突的,形成一个链表。
执行put方法时,根据key的hash值来计算放到table数组的下标,如果hash有相同的下标,则新put进去的元素放到Entry链的头部。
二. 属性与构造方法
属性:
static final int DEFAULT_INITIAL_CAPACITY = 16; //默认的初始大小,如果执行无参的构造方法,则默认初始大小为16
static final int MAXIMUM_CAPACITY = 1 << 30; //最大容量,1073741824
static final float DEFAULT_LOAD_FACTOR = 0.75f; //默认的负载因子,如果没有通过构造方法传入负载因子,则使用0.75。
transient Entry[] table; //存放具体键值对的Entry数组
transient int size; //存放元素的个数
int threshold; //阀值 threshold = (int)(capacity * loadFactor); 即容量*负载因子,执行put方法时如果size大于threshold则进行扩容,后面put方法将会看