一: 先说说hashmap的数据结构
哈希表+数组+链表+红黑树
二:看下hashmap的成员
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; //默认初始化数组的长度 static final int MAXIMUM_CAPACITY = 1 << 30; //最大数组长度 static final float DEFAULT_LOAD_FACTOR = 0.75f; //桶因子 static final int TREEIFY_THRESHOLD = 8; //链表装换成树的最小链表长度 static final int UNTREEIFY_THRESHOLD = 6; //树转换成链表的最大树元素个数 static final int MIN_TREEIFY_CAPACITY = 64; //链表转换成树的最小数组长度
/**
* The number of key-value mappings contained in this map.
*/
transient int size; //map的size
/**
* The next size value at which to resize (capacity * load factor).
*/
int threshold; //扩容阀值,capacity * load factor
三:向集合中添加元素的过程
1- size<threshold,直接插入元素;
size>threshold并且capacity <MIN_TREEIFY_CAPACITY,进行扩容;
size>threshold并且capacity >=MAXIMUM_CAPACITY,进入第二步;
2- 链表的长度小于TREEIFY_THRESHOLD,直接插入元素;
链表的长度大于TREEIFY_THRESHOLD并且capacity >MIN_TREEIFY_CAPACITY,链表转换为树;
注:删除元素时,满足树中元素小于UNTREEIFY_THRESHOLD时,会进行树转为链表。
四:hashSet实质上就是hashMap,只不过其值为Object
五:ConcurrentHashMap
ConcurrentHashMap 和 HashMap 思路是差不多的,但是因为它支持并发操作,所以要复杂一些。
整个 ConcurrentHashMap 由一个个 Segment 组成,Segment 代表”部分“或”一段“的意思,所以很多地方都会将其描述为分段锁。注意,行文中,我很多地方用了“槽”来代表一个 segment。
简单理解就是,ConcurrentHashMap 是一个 Segment 数组,Segment 通过继承 ReentrantLock 来进行加锁,所以每次需要加锁的操作锁住的是一个 segment,这样只要保证每个 Segment 是线程安全的,也就实现了全局的线程安全。
java7的segment数组一旦初始化以后,它是不可以扩容的。
java8是可以进行扩容的。 具体太繁琐。
参考内容:http://www.importnew.com/28263.html