Java基础-LinkedHashSet底层源码分析

package com.hspedu.linkedhash_;

import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;


@SuppressWarnings({"all"})
public class Course528 {
    public static void main(String[] args) {
        // LinkedHashSet源码


        /*
         *  1、LinkedHashSet是HashSet的子类,底层是LinkedHashMap,其底层是数组+双向链表(HashMap是单向链表)
         *  2、每一个节点都有before和after属性,形成双向链表
         *  3、LinkedHashSet根据元素的hashCode值决定元素的存储位置,如果已经存在则不添加
         *  4、因为是双向链表维护元素的次序,所以遍历元素是按照存储顺序
         *
         *  第一次添加元素时,将数组table扩容到16大小,存放的节点类型是LinkedHashMap$Entry
         *      数组(编译类型)类型是HashMap$Node[]类型,存放的数据类型(运行类型)是LinkedHashMap$Entry[]
         *
         * */


        Set set = new LinkedHashSet();
        set.add(new String("AA"));
        set.add(456);
        set.add(456);
        set.add(new Customer("刘", 1001));
        set.add(123);
        set.add("hsp");

        System.out.println("set = " + set);


        /*
            LinkedHashSet底层:LinkedHashMap,扩容机制和HashMap一样,初始tab大小16,临界阈值12(因子0.75)

            // 确定新增节点后,tab设置last节点分析:
            private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {
                LinkedHashMap.Entry<K,V> last = tail;       // 尾节点赋给last临时变量
                tail = p;                                   // 尾节点tail指向新的p节点
                if (last == null)                           // 如果该链表的last为null,新增节点同样是头节点
                    head = p;
                else {                                      // 如果该链表的last不为null
                    p.before = last;                        // 新增节点的before指向原来链表的尾节点
                    last.after = p;                         // 链表的尾节点指向新增节点p
                }
            }
        */
    }
}


@SuppressWarnings({"all"})
class Customer {
    private String name;
    private int no;

    public Customer(String name, int no) {
        this.name = name;
        this.no = no;
    }
}

 

posted @ 2022-03-23 17:09  柯南同学  阅读(32)  评论(0编辑  收藏  举报