How LinkedHashSet Works Internally In Java?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了How LinkedHashSet Works Internally In Java?相关的知识,希望对你有一定的参考价值。

LinkedHashSet is an extended version of HashSet. HashSet doesn’t follow any order where as LinkedHashSet maintains insertion order. HashSet uses HashMap object internally to store it’s elements where as LinkedHashSet uses LinkedHashMap object internally to store and process it’s elements. In this article, we will see how LinkedHashSet works internally and how it maintains insertion order.

Let’s start with constructors of LinkedHashSet class. There are 4 constructors in LinkedHashSet class. All these constructors are simply calling to super class constructor i.e constructor of HashSet class. Below is the how the constructors are defined in LinkedHashSet class.

理解:LinkedHashSet是HashSet的扩展版本.HashSet用HashMap对象来存储元素,而LinkedHashSet用LinkedHashMap对象来存储和处理它的元素.这篇文章讲了LinkedHashSet的工作原理还有它是如何保存元素的插入顺序的.

//Constructor - 1
 
public LinkedHashSet(int initialCapacity, float loadFactor)
{
      super(initialCapacity, loadFactor, true);              //Calling super class constructor
}
 
//Constructor - 2
 
public LinkedHashSet(int initialCapacity)
{
        super(initialCapacity, .75f, true);             //Calling super class constructor
}
 
//Constructor - 3
 
public LinkedHashSet()
{
        super(16, .75f, true);                //Calling super class constructor
}
 
//Constructor - 4
 
public LinkedHashSet(Collection<? extends E> c)
{
        super(Math.max(2*c.size(), 11), .75f, true);          //Calling super class constructor
        addAll(c);

In the above code snippet, you might have noticed that all 4 constructors are calling the same super class constructor. This constructor is a package private constructor which is used only by the LinkedHashSet class. This constructor takes initial capacity, load factor and one boolean dummy value as it’s arguments. This boolean dummy value is just used to differentiate this constructor from other constructors of HashSet class which take initial capacity and load factor as their arguments. Here is the how this constructor is defined in HashSet class.

理解:上面的四个构造函数都调用了非类相同的构造函数.这个构造函数是包私有函数,只会被LinkedHashSet所用.构造函数有三个参数,最后一个布尔变量是用来区别父类中另一个构造函数的.

HashSet(int initialCapacity, float loadFactor, boolean dummy)
{
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
}

As you are seeing, this constructor internally creates one new LinkedHashMapobject. This LinkedHashMap object is used by the LinkedHashSet to store it’s elements.

LinkedHashSet doesn’t have it’s own methods. All methods are inherited from it’s super class i.e HashSet. So. all operations on LinkedHashSet work in the same manner as that of HashSet. The only change is the internal object used to store the elements. In hashSet, elements you insert are stored as keys of HashMap object. Where as in LinkedHashSet, elements you insert are stored as keys of LinkedHashMap object. The values of these keys will be the same constant i.e “PRESENT“. We have seen this in How HashSet works internally in Java.

How LinkedHashSet Maintains Insertion Order?

LinkedHashSet uses LinkedHashMap object to store it’s elements. The elements you insert in the LinkedHashSet are stored as keys of this LinkedHashMap object. Eachkey, value pair in the LinkedHashMap are instances of it’s static inner class calledEntry<K, V>. This Entry<K, V> class extends HashMap.Entry class. The insertion order of elements into LinkedHashMap are maintained by adding two new fields to this class. They are before and after. These two fields hold the references to previous and next elements. These two fields make LinkedHashMap to function as a doubly linked list.

1
2
3
4
5
6
7
8
9
private static class Entry<K,V> extends HashMap.Entry<K,V>
{
        // These fields comprise the doubly linked list used for iteration.
        Entry<K,V> before, after;
 
        Entry(int hash, K key, V value, HashMap.Entry<K,V> next) {
            super(hash, key, value, next);
        }
}

The first two fields of above inner class of LinkedHashMap – before and after are responsible for maintaining the insertion order of the LinkedHashSet. The header field of LinkedHashMap stores the head of this doubly linked list. It is declared like below,

1
private transient Entry<K,V> header;        //Stores the head of the doubly linked list

In LinkedHashMap, the same set of Entry objects (rather references to Entry objects) are arranged in two different manner. One is the HashMap and another one is Doubly linked list. The Entry objects just sit on heap memory, unaware of that they are part of two different data structures.

Let’s see one example of LinkedHashSet to know how it works internally.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class LinkedHashSetExample
{
    public static void main(String[] args)
    {
        //Creating LinkedHashSet
 
        LinkedHashSet<String> set = new LinkedHashSet<String>();
 
        //Adding elements to LinkedHashSet
 
        set.add("BLUE");
 
        set.add("RED");
 
        set.add("GREEN");   
 
        set.add("BLACK");
    }
}

Look at the below image to see how above program works.

技术分享

If you know how LinkedHashMap works internally, it will be easy for you to understand how LinkedHashSet works internally. Go through source code of LinkedHashSet class and LinkedHashMap class once, you will get precise understanding about how LinkedHashSet works internally in Java.

以上是关于How LinkedHashSet Works Internally In Java?的主要内容,如果未能解决你的问题,请参考以下文章

How it works(14) GDAL2Tiles源码阅读

how_tomcat_works

How `delete’ works ?

How Hystrix Works?--官方

How WebAssembly Works

How Autofs Works