The Principle of HashSet, TreeSet, LinkedHashSet and the Use of Thread Security

1. Principles

 

        1,HashSet

        The underlying hashset layer actually maintains a HashMap instance.The underlying data structure is a hash table.Combines the advantages of arrays and chained lists.It has the following characteristics:

        (1) Collections of duplicate values are not allowed (hashCode() and equals() functions are used to determine whether duplicates exist).

        (2) There is no guarantee that the elements will be in the same order as they were added, or that the order may change (hashmap is maintained internally, hash modulus is used to determine the index position of the array, and then stored in the chain table).

        (3) HashSet is non-thread safe.

        (4) Collection element values can be nul.

    /**
    * Maintained hashMap instances
    */    
    private transient HashMap<E,Object> map;

    
    /**
     * Parameterless constructor, create a hashMap instance with a default load factor of 0.75
     */
    public HashSet() {
        map = new HashMap<>();
    }

    /**
     * Constructor containing specified set
     */
    public HashSet(Collection<? extends E> c) {
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        addAll(c);
    }

    /**
     * Constructor specifying initial capacity and load factor
     */
    public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
    }

    /**
     * Specify initial capacity with load factor of 0.75 as default
     */
    public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }

    /**
     * Constructors that specify capacity, load factor, and other access privileges
     */
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }

note: If you need to save an object of a class into a HashSet collection, when overriding the equals method and hashCode method of this class, try to ensure that when two objects return true by comparing equals, their hashCode method returns the same value.If equals are different, try to make hashcode values different to improve the efficiency of insertion.

       2,TreeSet

        TreeSet is an implementation class of the SortedSet interface, and TreeSet ensures that collection elements are sorted.The underlying data structure uses red and black trees.The default sort is from smallest to largest.A NavigableMap <E, Object> is maintained internally, and the map inherits SortMap.

public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable
{
    /**
     * The map inherits SortMap
     */
    private transient NavigableMap<E,Object> m;

    // 
    private static final Object PRESENT = new Object();

    /**
     * 
     */
    TreeSet(NavigableMap<E,Object> m) {
        this.m = m;
    }

    /**
     * 
     */
    public TreeSet() {
        this(new TreeMap<E,Object>());
    }

    /**
     * 
     */
    public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }

    /**
     * 
     */
    public TreeSet(Collection<? extends E> c) {
        this();
        addAll(c);
    }

    /**
     * 
     */
    public TreeSet(SortedSet<E> s) {
        this(s.comparator());
        addAll(s);
    }
}

 Compared to HashSet, TreeSet has the following functions:

        (1)Comparator comparator(): If the TreeSet uses a custom order, the method returns the Comparator used for the custom sort, and nul if the TreeSet uses a natural sort.
        (2)Object first(): Returns the first element in the collection.
        (3)Object last(): Returns the last element in the collection.
        (4)Object lower(Object e): Returns the element before the specified element.
        (5)Object higher(Object e): Returns the element after the specified element.
        (6)SortedSet subSet (Object fromElement, Object toElement): Returns a subset of this Set with no beginning or tail.
        (7)SortedSet headSet(Object toElement): Returns a subset of this Set consisting of elements smaller than toElement.
        (8)SortedSet tailSet(Object fromElement): Returns a subset of this Set consisting of elements greater than fromElement.

        3,LinkedHashSet

        linkedHashSet is a subclass of hashSet and is implemented based on LinkedHashMap.

/**
 * Inherit HashSet
 */
public class LinkedHashSet<E>
    extends HashSet<E>
    implements Set<E>, Cloneable, java.io.Serializable {

    private static final long serialVersionUID = -2851667679971038690L;

    /**
     * Constructor specifying capacity and load factor
     */
    public LinkedHashSet(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor, true);
    }

    /**
     * Specifies the capacity of the constructor whose load factor is 0.75 by default
     */
    public LinkedHashSet(int initialCapacity) {
        super(initialCapacity, .75f, true);
    }

    /**
     * Parameterless constructor, default capacity 16, load factor 0.75
     */
    public LinkedHashSet() {
        super(16, .75f, true);
    }

    /**
     * Constructor containing specified set
     */
    public LinkedHashSet(Collection<? extends E> c) {
        super(Math.max(2*c.size(), 11), .75f, true);
        addAll(c);
    }

    /**
     * java8 Splittable Iterator
     */
    @Override
    public Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, Spliterator.DISTINCT | Spliterator.ORDERED);
    }
}

        That's all the LinkedHashSet code. We don't see LinkedHashMap in it. Why is LinkedHashSet based on LinkedHashMap?

        Here we can see the constructor that calls the parent class in its constructor.

    /**
     * Specifies the capacity and load factor constructors, where the dummy parameter is used to distinguish other constructors for overloading.
     */
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }

2. Use of thread security

        Use Colletcions, a tool class syn method class, to create a thread-safe set.Set<String> synSet = Collections.synchronizedSet (new HashSet<>()).

Tags: Java linked list set

Posted on Sat, 04 Sep 2021 19:07:42 -0400 by p2grace