Introduction
The HashSet
class in Java is a member of the Java Collections Framework and it extends the AbstractSet
class and implements the Set
interface.
Key Points About HashSet Class
Unordered and Unsorted
The elements in a HashSet
are not ordered or sorted. There is no guarantee that the order will remain constant over time.
Unique Elements
HashSet
does not allow duplicate values. If you try to add the same value again, it will not replace the old value.
Null Elements
HashSet
allows one null value.
Non-Synchronized
HashSet
is non-synchronized, meaning it is not thread-safe and multiple threads can access it simultaneously.
Underlying Data Structure
HashSet
is implemented in terms of a hash table and internally uses HashMap
to store the elements.
Performance
The add
, remove
, and contains
methods have constant time complexity O(1).
Implements Set Interface
HashSet
implements the Set
interface, inheriting all its methods.
Initial Capacity and Load Factor
The default initial capacity of HashSet
is 16, and the default load factor is 0.75.
Create HashSet
Here is the syntax to create a HashSet
class object:
// Creating a HashSet
HashSet<String> set = new HashSet<>();
Add Elements to HashSet
We can use the add()
method to add elements to the HashSet
:
import java.util.HashSet;
public class Main {
public static void main(String[] args) {
// Creating a HashSet
HashSet<String> set = new HashSet<>();
// Adding new elements to the HashSet
set.add("Java");
set.add("Python");
set.add("JavaScript");
// Displaying the HashSet elements
for(String language : set){
System.out.println(language);
}
}
}
Output:
Java
JavaScript
Python
HashSet Contains One Null Value but Not Duplicate Values
HashSet
does not allow duplicate values and allows only one null value.
Here is a simple example that demonstrates this:
import java.util.HashSet;
public class HashSetExample {
public static void main(String[] args) {
HashSet<String> hset = new HashSet<>();
// Adding elements to the HashSet
hset.add("Apple");
hset.add("Mango");
hset.add("Grapes");
hset.add("Orange");
hset.add("Fig");
// Addition of duplicate elements
hset.add("Apple");
hset.add("Mango");
// Addition of null values
hset.add(null);
hset.add(null);
// Displaying HashSet elements
System.out.println(hset);
}
}
Output:
[null, Mango, Fig, Apple, Grapes, Orange]
Create HashSet from Another Collection
We can use the addAll()
method to add all the elements from an existing collection to a HashSet
.
Creating HashSet from Collection Example:
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Main {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(5);
list.add(10);
list.add(15);
list.add(20);
list.add(25);
List<Integer> list2 = new ArrayList<>();
list2.add(3);
list2.add(6);
list2.add(9);
list2.add(12);
list2.add(15);
// Creating a HashSet from another collection (ArrayList)
Set<Integer> set = new HashSet<>(list);
// Adding all the elements from an existing collection to a HashSet
set.addAll(list2);
System.out.println(set);
}
}
Output:
[3, 5, 6, 9, 10, 12, 15, 20, 25]
Access Elements
In Java, the HashSet
class does not have a get()
method to access its elements as it is not an indexed collection. However, you can iterate through a HashSet
to access its elements.
import java.util.HashSet;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
// Creating a HashSet
HashSet<String> set = new HashSet<>();
// Adding new elements to the HashSet
set.add("Java");
set.add("Python");
set.add("JavaScript");
// Accessing elements using an iterator
Iterator<String> iterator = set.iterator();
while(iterator.hasNext()){
String language = iterator.next();
System.out.println(language);
}
}
}
Output:
JavaScript
Java
Python
Remove Elements
We can remove elements from HashSet
using these methods:
remove(Object o)
: This method removes a single specified element from the set.removeAll(Collection c)
: This method removes all elements from the set that are contained in the specified collection.removeIf(Predicate<? super E> filter)
: This method removes all elements from the set that satisfy the given predicate.
import java.util.HashSet;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
// Creating a HashSet
HashSet<String> set = new HashSet<>();
set.addAll(Arrays.asList("Apple", "Banana", "Cherry", "Date", "Elderberry"));
System.out.println("Original HashSet: " + set);
// Using remove(Object o)
set.remove("Cherry");
System.out.println("\nAfter remove('Cherry'): " + set);
// Using removeAll(Collection c)
set.removeAll(Arrays.asList("Apple", "Banana"));
System.out.println("\nAfter removeAll(Arrays.asList('Apple', 'Banana')): " + set);
// Using removeIf(Predicate<? super E> filter)
set.removeIf(fruit -> fruit.startsWith("E"));
System.out.println("\nAfter removeIf(fruit -> fruit.startsWith('E')): " + set);
}
}
Output:
Original HashSet: [Date, Apple, Elderberry, Cherry, Banana]
After remove('Cherry'): [Date, Apple, Elderberry, Banana]
After removeAll(Arrays.asList('Apple', 'Banana')): [Date, Elderberry]
After removeIf(fruit -> fruit.startsWith('E')): [Date]
Iterate or Loop Through HashSet
Using Iterator
import java.util.HashSet;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("element 1");
set.add("element 2");
set.add("element 3");
set.add("element 4");
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
String str = iterator.next();
System.out.println(" only forward direction ---" + str);
}
}
}
Using Enhanced For Loop
public class Main {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("element 1");
set.add("element 2");
set.add("element 3");
set.add("element 4");
for (String str : set) {
System.out.println(" only forward direction ---" + str);
}
}
}
Using forEachRemaining() Method (Java 8)
import java.util.HashSet;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("element 1");
set.add("element 2");
set.add("element 3");
set.add("element 4");
Iterator<String> iterator = set.iterator();
iterator.forEachRemaining(str -> System.out.println(" only forward direction ---" + str));
}
}
Using forEach() Method (Java 8)
import java.util.HashSet;
public class Main {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("element 1");
set.add("element 2");
set.add("element 3");
set.add("element 4");
set.forEach(str -> System.out.println(" only forward direction ---" + str));
}
}
HashSet with User-Defined Objects
This example shows how to create a HashSet
of user-defined objects.
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
class Customer {
private long id;
private String name;
public Customer(long id, String name) {
this.id = id;
this.name = name;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// Two customers are equal if their IDs are equal
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Customer customer = (Customer) o;
return id == customer.id;
}
@Override
public int hashCode() {
return Objects.hash(id);
}
@Override
public String toString() {
return "Customer{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
public class Main {
public static void main(String[] args) {
Set<Customer> customers = new HashSet<>();
customers.add(new Customer(1, "Ramesh"));
customers.add(new Customer(2, "Pramod"));
customers.add(new Customer(3, "Sanjay"));
System.out.println(customers);
}
}
Output:
[Customer{id=1, name='Ramesh'}, Customer{id=2, name='Pramod'}, Customer{id=3, name='Sanjay'}]
Make HashSet Thread-Safe
In Java, HashSet
is not thread-safe, which means if it is used in a multi-threaded environment, then multiple threads can access and modify it simultaneously leading to data inconsistency. However, you can make a HashSet
thread-safe by using the Collections.synchronizedSet()
method.
Here is an example:
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("Apple");
set.add("Banana");
set.add("Cherry");
Set<String> synchronizedSet = Collections.synchronizedSet(set);
// Now you can use synchronizedSet in a multi-threaded environment safely
}
}
Conclusion
Congratulations folks! In this article, you learned what is a HashSet
, key points about HashSet
, how to create a HashSet
, how to add elements to a HashSet
, how to remove elements from the HashSet
, how to iterate over a HashSet
, and how to create a HashSet
of user-defined objects.
the usage of
ReplyDeleteforEachRemaining()
// Java 8
list.forEachRemaining(str -> System.out.println(" only forward direction ---" + str));
may not correct
if that have to instead of -> ?
ReplyDeleteIterator i = list.iterator();
i.next();
i.forEachRemaining(System.out::println);