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; } }