Hashset Java Example
1. Introduction
The HashSet class is a part of the Java Collection API since JDK 1.2. It extends from the AbstractSet class and implements the Set Java interface. It uses HashMap internally.

You can also check the Java Set Example in the following video:
The HashSet class contains unique elements. It permits the null element. It does not maintain the insertion order and is not thread-safe. In this example, I will demonstrate the following items:
- How to create a
HashSetobject - How to read, add, remove, and iterate elements in a
HashSet - Compare
HashSettoTreeSet - Compare
HashSettoLinkedHashSet
2. Technologies Used
The example code in this article was built and run using:
- Java 11
- Maven 3.3.9
- Eclipse Oxygen
- Junit 4.12
3. Maven Project
3.1 Dependencies
I will include Junit in the pom.xml.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>jcg.zheng.demo</groupId> <artifactId>java-hashset-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <build> <sourceDirectory>src</sourceDirectory> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <release>11</release> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies> </project>
4. JUnit Test
4.1 How to Construct HashSet
The HashSet class has four constructors:
HashSet()– Constructs a new empty set with default initial capacity (16) and load factor (0.75).HashSet(int initialCapacity)– Constructs a new empty set with the specified initial capacity and default load factor (0.75).HashSet(int initialCapacity, float loadFactor)– Constructs a new empty set with the specified initial capacity and the specified load factor.HashSet(Collection c)– Constructs a new set containing the elements in the specified collection.
In this step, I will show how to create a Hashset object via these four constructors. I emphasize the HashSet(Collection c) constructor with the following tests:
via_collection_list() – create aHashSetvia aListobjectvia_collection_set() – create aHashSetvia aSetobjectvia_stream() – create aHashSetviaStream.of
HashSet_ConstructorTest.java
package jcg.zheng.demo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.junit.Test;
public class HashSet_ConstructorTest {
@Test
public void via_collection_list() {
HashSet<String> fromAnotherCollection = new HashSet<>(Arrays.asList("Mary", "Zheng"));
assertFalse(fromAnotherCollection.isEmpty());
assertTrue(fromAnotherCollection.contains("Mary"));
assertTrue(fromAnotherCollection.contains("Zheng"));
}
@Test
public void via_collection_set() {
Set<String> fromCollectionUtils = Collections.singleton("Mary");
assertFalse(fromCollectionUtils.isEmpty());
assertTrue(fromCollectionUtils.contains("Mary"));
}
@Test
public void via_default_constructor() {
// Default initial capacity is 16
// Default load factor is 0.75
HashSet<String> createdByDefaultConstructor = new HashSet<>();
assertTrue(createdByDefaultConstructor.isEmpty());
}
@Test
public void via_initialCapacity_constructor() {
// initial capacity is 0
// Default load factor is 0.75
HashSet<String> createdByDefaultConstructor = new HashSet<>(0);
assertTrue(createdByDefaultConstructor.isEmpty());
}
@Test
public void via_initialCapacity_loadfactor_constructor() {
// initial capacity is 0
// load factor is 1
HashSet<String> createdByDefaultConstructor = new HashSet<>(0, 1);
assertTrue(createdByDefaultConstructor.isEmpty());
}
@Test
public void via_list() {
List<String> listHasDuplicates = Arrays.asList("Mary", "Zheng", "Mary", "Zheng");
assertEquals(4, listHasDuplicates.size());
HashSet<String> fromList = new HashSet<>(listHasDuplicates);
assertEquals(2, fromList.size());
}
@Test
public void via_stream() {
HashSet<String> fromStream = Stream.of("Mary", "Zheng").collect(Collectors.toCollection(HashSet::new));
assertFalse(fromStream.isEmpty());
assertTrue(fromStream.contains("Mary"));
assertTrue(fromStream.contains("Zheng"));
}
@Test
public void via_via_anonymous_collection() {
@SuppressWarnings("serial")
HashSet<String> fromAnonymousClass = new HashSet<>() {
{
add("Mary");
add("Zheng");
}
};
assertFalse(fromAnonymousClass.isEmpty());
assertTrue(fromAnonymousClass.contains("Mary"));
assertTrue(fromAnonymousClass.contains("Zheng"));
}
}
Output
Running jcg.zheng.demo.HashSet_ConstructorTest Tests run: 8, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.001 sec
4.2 HashSet Common Methods
There are several common methods in HashSet:
boolean isEmpty()– Returnstrueif this set contains no elements.Iterator<E> iterator()– Returns an iterator over the elements in this set.boolean add(E e)– Adds the specified element to this set if it is not already present. It has O(1) complexity.boolean remove(Object o)– Removes the specified element from this set if it is present. It has O(1) complexity.boolean contains(Object o)– Returns true if this set contains the specified element. It has O(1) complexity.int size()– Returns the number of elements in this set. It has O(1) complexity.
HashSet is not thread safe because it throws ConcurrentModificationException if multiple threads access a HashSet object concurrently, and at least one of the threads modifies the set. In this step, I will create test methods to demonstrate.
not_thread_safe_cannot_modify_while_iterate()– Iterate and modify aHashSetobject by calling theremove()method will throwConcurrentModificationExceptionuse_iterator_remove– it’s ok to remove the element via iterator.
HashSetTest.java
package jcg.zheng.demo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.junit.Test;
public class HashSetTest {
private Set<String> testClass = new HashSet<>();
@Test
public void can_add_null() {
assertTrue(testClass.isEmpty());
testClass.add(null);
assertFalse(testClass.isEmpty());
boolean removed = testClass.remove(null);
assertTrue(removed);
assertTrue(testClass.isEmpty());
}
@Test
public void can_read_while_iterate() {
testClass.add("Mary");
testClass.add("Zheng");
Iterator<String> iterator = testClass.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
System.out.println(item);
Iterator<String> iterator2 = testClass.iterator();
while (iterator2.hasNext()) {
System.out.println("\titerator2 " + iterator2.next());
}
}
testClass.clear();
assertTrue(testClass.isEmpty());
}
@Test
public void no_duplicate() {
assertTrue(testClass.isEmpty());
boolean added = testClass.add(null);
assertTrue(added);
assertFalse(testClass.isEmpty());
added = testClass.add("Mary");
assertTrue(added);
assertEquals(2, testClass.size());
added = testClass.add(null);
assertFalse(added);
added = testClass.add("Mary");
assertFalse(added);
boolean removed = testClass.remove("Mary");
assertTrue(removed);
assertEquals(1, testClass.size());
removed = testClass.remove("Mary");
assertFalse(removed);
}
@Test(expected = java.util.ConcurrentModificationException.class)
public void not_thread_safe_cannot_modify_while_iterate() {
testClass.add("Mary");
testClass.add("Zheng");
Iterator<String> iterator = testClass.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if ("Zheng".equalsIgnoreCase(item)) {
testClass.remove(item);// will throw exception
}
}
}
@Test
public void order_is_not_same_as_inserted() {
for (int i = 0; i < 19; i++) {
testClass.add(String.valueOf(i));
}
// [11, 12, 13, 14, 15, 16, 17, 18, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
System.out.println(testClass.toString());
}
@Test
public void use_iterator_remove() {
testClass.add("Mary");
testClass.add("Zheng");
Iterator<String> iterator = testClass.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if ("Zheng".equalsIgnoreCase(item)) {
iterator.remove();
}
}
assertEquals(1, testClass.size());
assertTrue(testClass.contains("Mary"));
assertFalse(testClass.contains("Zheng"));
}
}
Output
Running jcg.zheng.demo.HashSetTest
[11, 12, 13, 14, 15, 16, 17, 18, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Zheng
iterator2 Zheng
iterator2 Mary
Mary
iterator2 Zheng
iterator2 Mary
Tests run: 6, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.195 sec4.3 Compare to TreeSet
The TreeSet class extends from AbstractSet and the elements are ordered based on their natural ordering. TreeSet has unique element like HashSet. But TreeSet cannot have the null element.
In this step, I will use test methods to compare HashSet to TreeSet.
CompareToTreeSetTest.java
package jcg.zheng.demo;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
import org.junit.Test;
public class CompareToTreeSetTest {
private String[] listHasDuplicates = { "Shan", "Mary", "Mary", "Zheng", "Zheng" };
private Set<String> treeSet = new TreeSet<>();
@Test
public void HashSet_is_not_sorted_can_have_null() {
listHasDuplicates[listHasDuplicates.length - 1] = null;
assertEquals(5, listHasDuplicates.length);
Set<String> notOrderHashset = new HashSet<>(Arrays.asList(listHasDuplicates));
System.out.println(notOrderHashset);
assertEquals(4, notOrderHashset.size());
}
@Test(expected=ConcurrentModificationException.class)
public void not_thread_safe_because_cannot_modify_while_iterate() {
treeSet.add("Mary");
treeSet.add("Zheng");
treeSet.add("Tom");
Iterator<String> iterator = treeSet.iterator();
while (iterator.hasNext()) {
iterator.next();
treeSet.add("Test");
}
}
@Test(expected = NullPointerException.class)
public void TreeSet_can_not_have_null() {
treeSet.add(null);
}
@Test
public void TreeSet_is_sorted() {
assertEquals(5, listHasDuplicates.length);
TreeSet<String> orderedTreeSet = new TreeSet<>(Arrays.asList(listHasDuplicates));
System.out.println(orderedTreeSet);
assertEquals(3, orderedTreeSet.size());
assertEquals("Mary", orderedTreeSet.first());
assertEquals("Zheng", orderedTreeSet.last());
}
}
Output
Running jcg.zheng.demo.CompareToTreeSetTest [Mary, Shan, Zheng] [null, Shan, Zheng, Mary] Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.117 sec Results : Tests run: 4, Failures: 0, Errors: 0, Skipped: 0
4.4 Compare to LinkedHashSet
The LinkedHashSet class extends from HashSet. The only difference between them is that LinkedHashSet maintains the insertion order. In this step, I will create test methods to compare HashSet to LinkedHashSet.
CompareToLinkedHashSetTest.java
package jcg.zheng.demo;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.LinkedHashSet;
import org.junit.Test;
public class CompareToLinkedHashSetTest {
private String[] listHasDuplicates = { "Shan", "Mary", "Mary", "Zheng", "Zheng" };
private LinkedHashSet<String> setObj;
@Test
public void is_not_sorted_can_have_null() {
assertEquals(5, listHasDuplicates.length);
listHasDuplicates[listHasDuplicates.length - 1] = null;
assertEquals(5, listHasDuplicates.length);
setObj = new LinkedHashSet<>(Arrays.asList(listHasDuplicates));
System.out.println(setObj);
assertEquals(4, setObj.size());
}
@Test
public void LinkedHasSet_keeps_insertion_order() {
assertEquals(5, listHasDuplicates.length);
setObj = new LinkedHashSet<>(Arrays.asList(listHasDuplicates));
assertEquals(3, setObj.size());
//always "Shan", "Mary", "Zheng" order
System.out.println(setObj);
}
}
Output
Running jcg.zheng.demo.CompareToLinkedHashSetTest [Shan, Mary, Zheng] [Shan, Mary, Zheng, null] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.135 sec
5. Summary
In this example, I demonstrated several ways to create a HashSet object and how to use its common methods. I also compared HashSet to TreeSet and LinkedHashSet.
| HashSet | LinkedHashSet | TreeSet | |
|---|---|---|---|
| Unique Elements | Yes | Yes | Yes |
| Permit Null Element | Yes | Yes | No |
| Maintain Insertion Order | No | Yes | No |
| Is Sorted | No | No | Yes |
| Is thread-safe | No | No | No |
6. More articles
7. Download the Source Code
This example consists of a Maven project which contains several Junit tests to demonstrate the usage of the HashSet Class.
You can download the full source code of this example here: Hashset Java Example
Last updated on Apr. 23rd, 2021


