HashSet ClassThe HashSet class is the most common implementation of the Set interface. It is backed by a hash table (actually a HashMap instance).
HashSetSet implementations, it does not allow duplicate elements.LinkedHashSet (insertion order) or TreeSet (sorted order).null: A HashSet can contain one null element.add, remove, contains, and size), assuming the hash function disperses the elements properly among the buckets. This makes it the best-performing Set implementation for general use.HashSet WorksWhen you add an object to a HashSet, it calculates the object's hash code using its hashCode() method. This hash code is an integer that determines the "bucket" or location where the object should be stored in the underlying hash table.
When you check if an object contains() in the set, it first calculates the hash code to quickly find the right bucket, and then it uses the equals() method to check for an exact match among the few elements in that bucket.
Important: If you store custom objects in a
HashSet, you must properly implement both thehashCode()andequals()methods in your class. If you don't, theHashSetwill not be able to correctly identify duplicate objects.
HashSetHashSet is the ideal choice when you need a collection that:
It's perfect for tasks like finding unique items in a list or quickly checking for the existence of an item.
HashSet ExampleHere is an example demonstrating common operations on a HashSet.
import java.util.HashSet;public class Main { public static void main(String[] args) { HashSet<String> cars = new HashSet<String>(); // Add items cars.add("Volvo"); cars.add("BMW"); cars.add("Ford"); cars.add("BMW"); // This will be ignored cars.add("Mazda"); System.out.println(cars); // Note: The order is not guaranteed // Check if an item exists System.out.println("Contains 'Mazda': " + cars.contains("Mazda")); // Remove an item cars.remove("Volvo"); System.out.println("After removing Volvo: " + cars); // Loop through a HashSet System.out.println("--- Looping through cars ---"); for (String car : cars) { System.out.println(car); } } }
When you create a HashSet, it initializes an underlying hash table. By default, it has an initial capacity of 16 and a "load factor" of 0.75.
The load factor is a measure of how full the hash table is allowed to get before its capacity is automatically increased. A load factor of 0.75 means the set will double its capacity when it becomes 75% full.
If you know in advance how many elements you will store, you can set the initial capacity to avoid costly resizing operations.
import java.util.HashSet; import java.util.Set;public class Main { public static void main(String[] args) { // Initial capacity of 100, load factor of 0.8 // Optimized for storing around 80 items without resizing Set<String> optimizedSet = new HashSet<>(100, 0.8f); optimizedSet.add("Efficient"); System.out.println(optimizedSet); } }
Java 8 introduced the removeIf() method, which allows you to remove elements that match a certain condition (a Predicate) without needing to manually write an Iterator loop.
import java.util.HashSet; import java.util.Set; import java.util.Arrays;public class Main { public static void main(String[] args) { Set<Integer> numbers = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8)); // Remove all even numbers using a lambda expression numbers.removeIf(n -> n % 2 == 0); System.out.println("Odd numbers only: " + numbers); } }
What method must be properly implemented in your class to store objects in a HashSet correctly?