Java HashMap和HashSet源码

一: 先说说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

原文地址:https://www.cnblogs.com/parent-absent-son/p/10133549.html