天天看点

LinkedHashSet详解LinkedHashSet详解

LinkedHashSet详解

LinkedHashSet的全面说明

  • LinkedHashSet 是 HashSet 的子类
  • LinkedHashSet 底层是一个 LinkedHashMap(是HashMap的子类),底层维护了一个 数组+双向链表
  • LinkedHashSet 根据元素的 HashCode 值来决定元素的存储位置,同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的。
  • LinkedHashSet 不允许添加重复元素

LinkedHashSet的源码解读

  • LinkedHashSet 中维护了一个hash表和双向链表(LinkedHashSet 有 head 和 tail)
  • 每一个节点都有 before 和 after 属性,这样可以形成双向链表
  • 在添加一个元素时,先求hash值,再求索引,确定该元素在table的位置,然后将添加的元素加入到双向链表(如果已经存在,不添加[原则和HashSet一样])
  • 这样的话,我们遍历LinkedHashSet 也能确保插入顺序和遍历顺序一致、
public class Demo06 {
    public static void main(String[] args) {
        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);
    }
}
class Customer {
    private String name;
    private int no;
​
    public Customer(String name, int no) {
        this.name = name;
        this.no = no;
    }
}
           
LinkedHashSet详解LinkedHashSet详解

1.LinkedHashSet 集合添加和取出元素的顺序一致

LinkedHashSet详解LinkedHashSet详解

2.执行 set.add(new String("AA")); 

  • 第一次添加元素时,直接将table数组的大小扩容到16,存放的节点类型是 LinkedHashMap$Entry
LinkedHashSet详解LinkedHashSet详解

数组的类型是 HashMap$Node,存放的元素的类型是 LinkedHashMap$Entry

  • LinkedHashMap 中的静态内部类 Entry
static class Entry<K,V> extends HashMap.Node<K,V> {
    Entry<K,V> before, after;
    Entry(int hash, K key, V value, Node<K,V> next) {
        super(hash, key, value, next);
    }
}
           
  • HashMap中的静态内部类 Node
//实现的是Map接口中的Entry接口
static class Node<K,V> implements Map.Entry<K,V>