HashSet & LinkedHashSet in the Java Collections Framework

Nimasha Madhushani
6 min readFeb 10, 2024
image by author

Hey Guys, I hope you have already read the first 3 articles of the Java Collections Framework Article Series. If not, this is for you.

image by author

HashSets

🟣Concepts in HashSets,

  • Duplicate elements are not allowed.
  • Insertion order is not preserved. Elements are in a random order. So, there is no index concept.
  • Insert element using the concept called HashCode. It helps to fetch elements in a HashSet faster.
  • Heterogeneous data will be supported.
  • Null values are supported. So, we can add null values in the HashSets.

If need to fetch many elements, the most suitable concept is HashSet, because It’s very fast.

We’ll see how elements can be allocated to a HashSet.

  • HashSet hashSet = new HashSet(); , HashSet() is the default/empty constructor. There, 16 allocations are available by default/initially. So, we can store 16 objects/elements.

Load Factor / Fill Ratio

The load factor concept in HashSets is very important.

  • ArrayList arrayList = new ArrayList(); , the default size is 10. So, 10 elements can be stored.
  • Assume, that you need to insert the 11th element. Then a new ArrayList will be created and, elements in the old ArrayList will be added to this new ArrayList and then the 11th element will be added finally. Then the old ArrayList will be added to the garbage collection.

The load factor in the HashSet is 0.75. If the HashSet is filled with 0.75, then a new HashSet will be created. And the elements in the old HashSet are added to this new HashSet.

  • HashSet hashSet = new HashSet(100);, the load factor is 0.75
  • HashSet hashSet = new HashSet(100, 0.95);, the load factor is 0.95
  • HashSet<Integer> hashSet = new HashSet(); , Integer elements will be stored here.

HashSet has no specific/own methods. So, the methods which are in the Set interface are implemented in the HashSet class.

💦Methods available in the Set Interface

  • add(value); — An element will be added to the HashSet

The index concept is not used in HashSets. So, there are no index-based insertions. Because, in HashSet, elements are arranged in random order. Furthermore, we can’t do the sorting and shuffling as well. If needed, we have to convert this HashSet into an ArrayList and apply sortings/shufflings.

  • addAll(Collection); — A group of elements will be added to the HashSet
  • remove(value); — An element will be removed from the HashSet Collection
  • removeAll(Collection); — A group of elements will be removed from the HashSet
  • contains(element); — Check the availability of the element in the HashSet. If that element is available this will return true and otherwise it return false.
  • containsAll(Collection); — Check the availability of a group of elements in the HashSet. If that group of elements is available this will return true and otherwise it return false.
  • isEmpty(); — If the HashSet is empty this will return true, otherwise false will be returned.

So, guys, we will try these methods,

import java.util.HashSet;
import java.util.Iterator;

public class HashSetDemo1 {
public static void main(String[] args) {
HashSet hashSet = new HashSet();//default capacity is 16, load factor is 0.75
HashSet hashSet1 = new HashSet(100);//initial capacity 100
HashSet hashSet2 = new HashSet(100, (float) 0.90);

HashSet<Integer> integerHashSet = new HashSet<>();

//add elements/objects into HashSet
hashSet.add(75);
hashSet.add("Welcome");
hashSet.add(12.3);
hashSet.add('A');
hashSet.add(true);
hashSet.add(null);

System.out.println(hashSet);//insertion order not preserved

//remove
hashSet.remove(12.3);
System.out.println("After removing a value : " + hashSet);

//contains
System.out.println("Check for \"Welcome\" : " + hashSet.contains("Welcome"));
System.out.println("Check for \"Java\" : " + hashSet.contains("Java"));
System.out.println("Check for isEmpty : " + hashSet.isEmpty());

//Reading elements/objects from the hashset
for (Object element : hashSet
) {
System.out.print(element + " ");
}
System.out.println();
Iterator iterator = hashSet.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}

HashSet<Integer> evenNumber = new HashSet<>();
evenNumber.add(2);
evenNumber.add(4);
evenNumber.add(6);
System.out.println("HashSet : " + evenNumber);

HashSet<Integer> numbers = new HashSet<>();

//addAll
numbers.addAll(evenNumber);
numbers.add(10);
System.out.println("New HashSet : " + numbers);

//removeAll
numbers.removeAll(evenNumber);
System.out.println("After removing all even numbers : " + numbers);
}
}

Output:

[null, A, 12.3, Welcome, 75, true]
After removing a value : [null, A, Welcome, 75, true]
Check for "Welcome" : true
Check for "Java" : false
Check for isEmpty : false
null A Welcome 75 true
null A Welcome 75 true HashSet : [2, 4, 6]
New HashSet : [2, 4, 6, 10]
After removing all even numbers : [10]

Now, we will see how to get the union, intersection, and the difference in HashSets

Union

import java.util.HashSet;

public class HashSetDemo2 {
public static void main(String[] args) {
HashSet<Integer> integerHashSet1 = new HashSet<>();
integerHashSet1.add(1);
integerHashSet1.add(2);
integerHashSet1.add(3);
integerHashSet1.add(4);
integerHashSet1.add(5);

System.out.println("HashSet 1 : " + integerHashSet1);

HashSet<Integer> integerHashSet2 = new HashSet<>();
integerHashSet2.add(3);
integerHashSet2.add(4);
integerHashSet2.add(5);
integerHashSet2.add(6);

System.out.println("HashSet 2 : " + integerHashSet2);

//union
integerHashSet1.addAll(integerHashSet2);
System.out.println("Union : " + integerHashSet1);
}
}

Output of Union:

HashSet 1 : [1, 2, 3, 4, 5]
HashSet 2 : [3, 4, 5, 6]
Union : [1, 2, 3, 4, 5, 6]

Intersection

import java.util.HashSet;

public class HashSetDemo2 {
public static void main(String[] args) {
HashSet<Integer> integerHashSet1 = new HashSet<>();
integerHashSet1.add(1);
integerHashSet1.add(2);
integerHashSet1.add(3);
integerHashSet1.add(4);
integerHashSet1.add(5);

System.out.println("HashSet 1 : " + integerHashSet1);

HashSet<Integer> integerHashSet2 = new HashSet<>();
integerHashSet2.add(3);
integerHashSet2.add(4);
integerHashSet2.add(5);
integerHashSet2.add(6);

System.out.println("HashSet 2 : " + integerHashSet2);

//intersection
integerHashSet1.retainAll(integerHashSet2);
System.out.println("Intersection : " + integerHashSet1);
}
}

Output of Intersection:

HashSet 1 : [1, 2, 3, 4, 5]
HashSet 2 : [3, 4, 5, 6]
Intersection : [3, 4, 5]

Difference

import java.util.HashSet;

public class HashSetDemo2 {
public static void main(String[] args) {
HashSet<Integer> integerHashSet1 = new HashSet<>();
integerHashSet1.add(1);
integerHashSet1.add(2);
integerHashSet1.add(3);
integerHashSet1.add(4);
integerHashSet1.add(5);

System.out.println("HashSet 1 : " + integerHashSet1);

HashSet<Integer> integerHashSet2 = new HashSet<>();
integerHashSet2.add(3);
integerHashSet2.add(4);
integerHashSet2.add(5);
integerHashSet2.add(6);

System.out.println("HashSet 2 : " + integerHashSet2);

//difference
integerHashSet1.retainAll(integerHashSet2);
System.out.println("Difference : " + integerHashSet1);
}
}

Output of Difference:

HashSet 1 : [1, 2, 3, 4, 5]
HashSet 2 : [3, 4, 5, 6]
Difference : [3, 4, 5]

Subset

import java.util.HashSet;

public class HashSetDemo2 {
public static void main(String[] args) {
HashSet<Integer> integerHashSet1 = new HashSet<>();
integerHashSet1.add(1);
integerHashSet1.add(2);
integerHashSet1.add(3);
integerHashSet1.add(4);
integerHashSet1.add(5);

System.out.println("HashSet 1 : " + integerHashSet1);

HashSet<Integer> integerHashSet2 = new HashSet<>();
integerHashSet2.add(3);
integerHashSet2.add(4);
integerHashSet2.add(5);
integerHashSet2.add(6);

System.out.println("HashSet 2 : " + integerHashSet2);

//subset
integerHashSet1.containsAll(integerHashSet2);
System.out.println("Subset : " + integerHashSet1);
}
}

Output subset:

HashSet 1 : [1, 2, 3, 4, 5]
HashSet 2 : [3, 4, 5, 6]
Subset : [1, 2, 3, 4, 5]

LinkedHashSets

In linkeHashSets also default memory allocation is 16 and the load factor is 0.75 initially.

The methods available in the HashSet are available inside the LinkedHashSet as well.

import java.util.LinkedHashSet;

public class LinkedHashSetDemo {
public static void main(String[] args) {
LinkedHashSet<Integer> integerLinkedHashSet = new LinkedHashSet<>();
LinkedHashSet linkedHashSet = new LinkedHashSet();
linkedHashSet.add(100);
linkedHashSet.add(200);
linkedHashSet.add(300);
linkedHashSet.add(400);
linkedHashSet.add(500);

System.out.println(linkedHashSet);
}
}

Output:

[100, 200, 300, 400, 500]

Ok..😎! Now we have discussed a lot. Let’s have a summary of the points we discussed.

  • HashSet has a HashTable data structure.
  • LinkedHashSet has a HashTable + LinkedList data structure.
image by author

Cool…! Yes, guys, It’s time to have a break. Let’s meet with part 5 of this blog series to discuss other things.

So, Stay tuned…!

Until then bye to you…👋🏼👋🏼👋🏼

--

--