1、本人博客《HashMap、HashSet底层原理分析》
 2、本人博客《若debug时显示的Hashmap没有table、size等元素时,查看第19条》
结论
1、链表长度大于8时(插入第9条时),会触发树化(treeifyBin)方法,但是不一定会树化,若数组大小小于64时,则会先扩容。
 2、假设扩容后该链表重新计算Hash后还是放在同一个数组下标时,则会出现链表长度大于8时,未树化的情况。
jdk8源码(treeifyBin)
final void treeifyBin(Node<K,V>[] tab, int hash) {
    int n, index; Node<K,V> e;
    // MIN_TREEIFY_CAPACITY = 64
    // 链表长度小于64时会优先扩容
    if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
        resize();
    else if ((e = tab[index = (n - 1) & hash]) != null) {
        TreeNode<K,V> hd = null, tl = null;
        do {
            TreeNode<K,V> p = replacementTreeNode(e, null);
            if (tl == null)
                hd = p;
            else {
                p.prev = tl;
                tl.next = p;
            }
            tl = p;
        } while ((e = e.next) != null);
        if ((tab[index] = hd) != null)
            hd.treeify(tab);
    }
}
测试源码(大于8时,未树化)
import java.util.HashMap;
import java.util.Objects;
public class HashmapTest {
    public static void main(String[] args) {
        HashMap<User,User> hashMap = new HashMap<>();
        // 同一链表插入8条
        for (int i = 0; i < 8; i++) {
            hashMap.put(new User("张三", 18),new User("张三", i));
        }
        // 插入第九条,链表长度大于8,会进入treeifyBin树化方法,但是未树化,会执行扩容方法
        // 默认数组大小16扩容到32
        // 链表长度变成了9个Node节点,并非红黑树
        hashMap.put(new User("张三", 18),new User("张三", 9));
        // 插入第10条,链表长度大于8,会进入treeifyBin树化方法,但是未树化,会执行扩容方法
        // 数组大小由32扩容到了64
        // 链表长度变成了10个Node节点,并非红黑树
        hashMap.put(new User("张三", 18),new User("张三", 10));
        // 插入第十一条时树化
        // 数组容量还是64未触发扩容
        // 链表变成红黑树,节点由Node变成TreeNode
        hashMap.put(new User("张三", 18),new User("张三", 11));
    }
}
// 重写hashCode方法,保证值一样是hashcode是一样的,可以使值一样的对象出现在同一链表上
class User{
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
插入第九条时的Hashmap
 插入第十条时结果是一样的,只是数组扩容到了64
 1、数组长度扩容到了32
 2、Hashmap中保存了9个数据,均在同一条链表
 3、节点为Node节点,并不是treenode(红黑树)
 
 插入第十一条时的Hashmap
 1、数组大小为64
 2、节点变成了treenode(红黑树)
 
测试源码(大于8时,树化)
初始化Hashmap时,直接大于等于64,则同一个链表插入第九条时直接执行了树化。
 treeifyBin方法中只有数组长度小于64时才会执行扩容方法,否则则是树化
// 初始化大小,其他同上,插入第九条时,节点就变成了treenode
HashMap<User,User> hashMap = new HashMap<>(64);
插入第九条时的Hashmap
 1、数组大小为64
 2、节点变成了treenode(红黑树)
 



















