天天看點

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>