LinkedHashSet in java

We have read about the Set interface and the most common implementation of Set are HashSet, LinkedHashSet, and TreeSet. In this post, we will read LinkedHashSet in java and LinkedHashSet example in java.

NOTE: HashSet doesn’t maintain the order of elements. It is an unorder implementation of the Set interface.
LinkedHashSet
maintains the insertion order of elements.
TreeSet
maintains the ascending order of elements.

You can read it with an example from here.
1. What is LinkedHashSet in java?
2. Important points about Java LinkedHashSet?
3. What are the initial capacity and load factor?
4. Creation of LinkedHashSet in java?
5. The constructor of LinkedHashSet class?
6. Order of Insertion?
7. When to use LinkedHashSet?
8. Internal working of LinkedHashSet?
9. HashSet vs LinkedHashSet?

1. What is LinkedHashSet in java

The LinkedHashSet class is a part of the Java Collection Framework that implements the Set interface and extends the HashSet class. It also implements the Cloneable and Serializable interface.

LinkedHashSet in java

LinkedHashSet is like HashSet except it maintains the insertion order of elements. LinkedHashSet class uses the hash table and linked list for storage and maintain the order of elements. LinkedHashSet collection is very useful when the programmer wants to store only unique objects with their insertion order because it is an ordered version of HashSet. The capacity grows automatically as elements are added in the LinkedHashSet.

2. Important points about Java LinkedHashSet

1. The LinkedHashSet extends HashSet class, it means it contains all the properties from HashSet.

2. Like HashSet duplicate values are not allowed in LinkedHashSet. If you want to know Why duplicate not allowed in HashSet?

3. Like HashSet, LinkedHashSet allows only one NULL. If you want to know Why HashSet can contain only one null?

4. Unlike HashSet, LinkedHashSet maintains the insertion order of elements because it uses the doubly LinkedList internally to store the data.

5 A LinkedHashSet is not synchronized by default. So if we want to use it in a multithreading environment then it must be synchronized externally.

6. We can’t modify the LinkedHashSet during traverse because it throws ConcurrentModificationException.

3. The initial capacity and load factor

The default capacity of LinkedHashSet is 16 and the load factor is 0.75.  It means JVM creates 16 numbers of buckets when LinkedHashSet is created. It increases the capacity automatically if the current size gets full.

The capacity increase based on threshold and threshold is equal to (DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY). The JVM increases the number of buckets when LinkedHashSet elements count exceeds this threshold. It makes its capacity is double the previous capacity. In LinkedHashSet, threshold will be (16*0.75 = 12).

4. Creation of LinkedHashSet in java

The LinkedHashSet internally uses the LinkedHashMap, whenever we create an object of LinkedHashSet it internally creates an object LinkedHashMap. LinkedHashSet provides four constructors that are used to create a LinkedHashSet. Each constructor has a different use case, that needs a different type of parameters. Each constructor internally creates an object of LinkedHashMap.

5. The constructor of LinkedHashSet class

LinkedHashSet()

The LinkedHashSet() is the default constructor of LinkedHashSet class. It creates a new and empty LinkedHashSet in heap memory. It doesn’t take any parameter. It creates a LinkedHashSet with default capacity 12and load factor 0.75. It internally invokes the constructor of the HashSet class by use of Super keyword.

public LinkedHashSet() {
        super(16, .75f, true);
    }

Let’s take an example of LinkedHashSet

import java.util.LinkedHashSet;

public class LinkedHashSetExample
{
	public static void main(String arg[])
	{
		LinkedHashSet<String> stringLinkedHashSet = new LinkedHashSet<String>();
		stringLinkedHashSet.add("Hi");
		stringLinkedHashSet.add("Java");
		stringLinkedHashSet.add("Goal");
		stringLinkedHashSet.add("Learning");
		stringLinkedHashSet.add("Website");
		
		System.out.println("Strings from LinkedHashSet: "+stringLinkedHashSet);
		
		LinkedHashSet<Integer> integerLinkedHashSet = new LinkedHashSet<Integer>();
		integerLinkedHashSet.add(1);
		integerLinkedHashSet.add(2);
		integerLinkedHashSet.add(3);
		integerLinkedHashSet.add(4);
		integerLinkedHashSet.add(5);
		
		System.out.println("Integer from LinkedHashSet: "+integerLinkedHashSet);
		
	}
}

Output: Strings from LinkedHashSet: [Hi, Java, Goal, Learning, Website]
Integer from LinkedHashSet: [1, 2, 3, 4, 5] 

LinkedHashSet(int initialCapacity)

It is a parameterized constructor that takes the initial capacity of LinkedHashSet. It creates an empty LinkedHashSet with a specified capacity and default load factor that is 0.75. It takes a parameter of int type i.e. capacity of LinkedHashSet. It throws IllegalArgumentException if the parameter value is less than 0. This constructor also invokes the constructor of the HashSet class by use of Super keyword.

public LinkedHashSet(int initialCapacity) {
        super(initialCapacity, .75f, true);
    }
import java.util.LinkedHashSet;

public class LinkedHashSetExample
{
	public static void main(String arg[])
	{
		LinkedHashSet<String> stringLinkedHashSet = new LinkedHashSet<String>(10);
		stringLinkedHashSet.add("Hi");
		stringLinkedHashSet.add("Java");
		stringLinkedHashSet.add("Goal");
		stringLinkedHashSet.add("Learning");
		stringLinkedHashSet.add("Website");
		
		System.out.println("Strings from LinkedHashSet: "+stringLinkedHashSet);
		
		LinkedHashSet<Integer> integerLinkedHashSet = new LinkedHashSet<Integer>(10);
		integerLinkedHashSet.add(1);
		integerLinkedHashSet.add(2);
		integerLinkedHashSet.add(3);
		integerLinkedHashSet.add(4);
		integerLinkedHashSet.add(5);
		
		System.out.println("Integer from LinkedHashSet: "+integerLinkedHashSet);
		
	}
}

Output: Strings from LinkedHashSet: [Hi, Java, Goal, Learning, Website]
Integer from LinkedHashSet: [1, 2, 3, 4, 5] 

LinkedHashSet(int initialCapacity, float loadFactor)

It is also a parameterized constructor that takes the initial capacity and load factor of LinkedHashSet. It creates an empty LinkedHashSet with a given capacity and load factor. It takes two parameters one is of int type and another is float type. It throws IllegalArgumentException if the initial capacity is less than 0 or load factor is a non-positive integer. This constructor also invokes the constructor of the HashSet class by use of Super keyword.

public LinkedHashSet(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor, true);
    }
import java.util.LinkedHashSet;

public class LinkedHashSetExample
{
	public static void main(String arg[])
	{
		LinkedHashSet<String> stringLinkedHashSet = new LinkedHashSet<String>(10, .80f);
		stringLinkedHashSet.add("Hi");
		stringLinkedHashSet.add("Java");
		stringLinkedHashSet.add("Goal");
		stringLinkedHashSet.add("Learning");
		stringLinkedHashSet.add("Website");
		
		System.out.println("Strings from LinkedHashSet: "+stringLinkedHashSet);
		
		LinkedHashSet<Integer> integerLinkedHashSet = new LinkedHashSet<Integer>(10, .80f);
		integerLinkedHashSet.add(1);
		integerLinkedHashSet.add(2);
		integerLinkedHashSet.add(3);
		integerLinkedHashSet.add(4);
		integerLinkedHashSet.add(5);
		
		System.out.println("Integer from LinkedHashSet: "+integerLinkedHashSet);
		
	}
}

Output: Strings from LinkedHashSet: [Hi, Java, Goal, Learning, Website]
Integer from LinkedHashSet: [1, 2, 3, 4, 5] 

LinkedHashSet(Collection<? extends E> c)

This constructor is used to create a LinkedHashSet with a given collection. It takes all the elements from collection and adds to the object of LinkedHashSet. It doesn’t accept the duplicate element from the collection and ignore the element.  It throws NullPointerException if the given collection is null. This constructor also invokes the constructor of the HashSet class by use of Super keyword.

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




import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;

public class LinkedHashSetExample
{
	public static void main(String arg[])
	{
		HashSet<String> stringHashSet = new HashSet<String>();
		stringHashSet.add("Hi");
		stringHashSet.add("Java");
		stringHashSet.add("Goal");
		stringHashSet.add("Learning");
		stringHashSet.add("Website");
		
		ArrayList<String> stringArrayList =  new ArrayList<String>();
		stringArrayList.add("Java");
		stringArrayList.add("Java");
		stringArrayList.add("Goal");
		stringArrayList.add("Learning");
		stringArrayList.add("Learning");
		
		LinkedHashSet<String> firstLinkedHashSet =  new LinkedHashSet<String>(stringHashSet);
		LinkedHashSet<String> secondLinkedHashSet =  new LinkedHashSet<String>(stringArrayList);
		
		System.out.println("First LinkedHashSet: "+ firstLinkedHashSet);
		System.out.println("Second LinkedHashSet: "+ secondLinkedHashSet);
	}
}

Output: First LinkedHashSet: [Learning, Hi, Java, Goal, Website]
Second LinkedHashSet: [Java, Goal, Learning]

6. Order of Insertion

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;

public class LinkedHashSetExample
{
	public static void main(String arg[])
	{
		HashSet<String> stringHashSet = new HashSet<String>();
		stringHashSet.add("A");
		stringHashSet.add("Z");
		stringHashSet.add("B");
		stringHashSet.add("D");
		stringHashSet.add("R");
		
		LinkedHashSet<String> stringLinkedHashSet = new LinkedHashSet<String>();
		stringLinkedHashSet.add("A");
		stringLinkedHashSet.add("Z");
		stringLinkedHashSet.add("B");
		stringLinkedHashSet.add("D");
		stringLinkedHashSet.add("R");
		
		System.out.print("Elements from HashSet: ");
		for(String obj : stringHashSet)
			System.out.println(obj);
		
		System.out.print("Elements from LinkedHashSet: ");
		for(String obj : stringLinkedHashSet)
			System.out.println(obj);
		
	}
}

Output: Data from HashSet: A
B
R
D
Z
Data from LinkedHashSet: A
Z
B
D
R

7. When to use LinkedHashSet

A LinkedHashSet implements Set interface, So, it contains only a unique element like HashSet, and it maintains an insertion order also. So, whenever we want to store the unique elements with their insertion order, then we can use LinkedHashSet.

Let’s take an example, suppose we are maintaining the voting booth in the election. So, there are two conditions:
1. A person can draw voting only one time. It means the object of person class must be unique.
2. The voting process works based on first come first serve. It means we need to maintain the order of objects.

import java.util.LinkedHashSet;

class Person
{
	int voterId;
	String name;
	public int getVoterId() {
		return voterId;
	}
	public void setVoterId(int voterId) {
		this.voterId = voterId;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Person(int voterId, String name) {
		this.voterId = voterId;
		this.name = name;
	}
	@Override
	public int hashCode() 
	{
		return voterId;
	}
	@Override
	public boolean equals(Object obj) 
	{
		if (this == obj)
			return true;
		if (obj == null || getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (voterId != other.voterId)
			return false;
		return true;
	}
}

public class LinkedHashSetExample
{
	public static void main(String arg[])
	{
		LinkedHashSet<Person> personsData = new LinkedHashSet<Person>();
		personsData.add(new Person(103, "Ram"));
		personsData.add(new Person(101, "John"));
		personsData.add(new Person(105, "Krishana"));
		
		for(Person person: personsData)
			System.out.println("Name: "+person.getName()+ ", VoterId: "+person.getVoterId());
	}
	
}

Output: Name: Ram, VoterId: 103
Name: John, VoterId: 101
Name: Krishana, VoterId: 105

8. Internal working of LinkedHashSet

We have learned what is LinkedHashSet in java and when we should use the LinkedHashSet. LinkedHashSet maintains the insertion order of element and the interviewer always asks how LinkedHashSet maintains the order of element? In this post, we see the internally working of LinkedHashSet and find out how it maintains order of elements.

The LinkedHashSet internally uses the LinkedHashMap that maintains the order of insertion by use of Hash Table and doubly linked list. Whenever we call the constructor of LinkedHashSet class, it internally invokes the constructor of the HashSet class by use of Super keyword. Let’s have a look at JDK:

public LinkedHashSet()
{
     super(16, .75f, true);
}

Here you can see the default constructor of LinkedHashSet that calling the constructor of super class i.e. HashSet. The constructor of the HashSet class creates an object of LinkedHashMap and stores all the elements in LinkedHashMap. The LinkedHashMap works based on Hash Table and Linked list.

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

So, when  we perform an operation on LinkedHashSet, the JVM internally perform those operations on LinkedHashMap.

Leave a Comment