HashMap在Java8之后就不再用link data bins了,而是转为用Treeify的bins,至于为什呢呢?官方有以下解释:
* This map usually acts as a binned (bucketed) hash table, but
* when bins get too large, they are transformed into bins of
* TreeNodes, each structured similarly to those in
* java.util.TreeMap. Most methods try to use normal bins, but
* relay to TreeNode methods when applicable (simply by checking
* instanceof a node). Bins of TreeNodes may be traversed and
* used like any others, but additionally support faster lookup
* when overpopulated. However, since the vast majority of bins in
* normal use are not overpopulated, checking for existence of
* tree bins may be delayed in the course of table methods.
其实很好理解,当Hash冲突过多的时候,树节点肯定比链表更能提升性能,可是绝大多数情况下是不会用到的,首先是用HashMap一般要求是随机的Hash,再者0.7的loadfactor,意味着我们的要求是装不满。可是也并不是所有冲突都是用树节点,而是当冲突数超过6的时候才有可能用到,可见几率比较少。在这里还有注意,树化和链表化是随着节点数互相转换的,分别对应一个threshold,见如下文档解析。
/**
* The bin count threshold for using a tree rather than list for a
* bin. Bins are converted to trees when adding an element to a
* bin with at least this many nodes. The value must be greater
* than 2 and should be at least 8 to mesh with assumptions in
* tree removal about conversion back to plain bins upon
* shrinkage.
*/
static final int TREEIFY_THRESHOLD = 8;
/**
* The bin count threshold for untreeifying a (split) bin during a
* resize operation. Should be less than TREEIFY_THRESHOLD, and at
* most 6 to mesh with shrinkage detection under removal.
*/
static final int UNTREEIFY_THRESHOLD = 6;