Java HashSet is a class in the Java Collections Framework that implements the Set interface. It is an unordered collection of unique elements, where each element is stored only once.
Some important features of Java HashSet include:
- It does not maintain the order of elements in which they were inserted.
- It uses hashing to store elements, which allows for fast insertion, deletion, and retrieval of elements.
- It does not allow duplicate elements. If you try to add a duplicate element, it will simply be ignored.
- It allows null values.
- It provides constant-time performance for the basic operations (add, remove, contains, and size) as long as the hash function distributes the elements evenly among the buckets.
Here’s an example of how to create and use a HashSet in Java:
import java.util.HashSet; public class HashSetExample { public static void main(String[] args) { HashSet<String> set = new HashSet<>(); set.add("apple"); set.add("banana"); set.add("orange"); set.add("pear"); set.add("banana"); // this will be ignored since it's a duplicate System.out.println(set); // prints [orange, pear, banana, apple] System.out.println(set.contains("apple")); // prints true System.out.println(set.size()); // prints 4 } }
Difference between List and Set:
In Java, List and Set are two different interfaces in the Collections framework that are used to store a group of objects. The main difference between List and Set is that List allows duplicate elements, while Set does not.
Here are some key differences between List and Set:
- Duplicate Elements: List allows duplicate elements while Set doesn’t. In other words, you can add the same element multiple times to a List, but in a Set, duplicates are automatically removed.
- Order: List maintains the order of elements in which they were inserted, whereas Set does not maintain the order of elements. In other words, if you add elements to a List in a particular order, the order will be preserved when you retrieve them, but in a Set, the order is not guaranteed.
- Index-based Operations: List provides index-based operations, which means you can access elements by their index number, add elements at a particular index, or remove elements at a particular index. Set does not provide such operations, as it does not maintain any order.
- Implementation: List is implemented using an ordered sequence, whereas Set is implemented using a hash table.
- Performance: List is generally faster than Set when it comes to accessing elements by index, but slower when it comes to checking whether an element is present. Set is faster than List when it comes to checking whether an element is present.
Here’s an example to illustrate the difference between List and Set:
import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; public class ListSetExample { public static void main(String[] args) { // Creating a List List<String> myList = new ArrayList<>(); myList.add("apple"); myList.add("banana"); myList.add("orange"); myList.add("apple"); // duplicate element // Creating a Set Set<String> mySet = new HashSet<>(); mySet.add("apple"); mySet.add("banana"); mySet.add("orange"); mySet.add("apple"); // duplicate element will be ignored System.out.println("List: " + myList); // prints [apple, banana, orange, apple] System.out.println("Set: " + mySet); // prints [orange, banana, apple] } }
In the example above, we created a List and a Set with the same elements. When we print the List, we can see that it contains the duplicate element “apple”, but when we print the Set, the duplicate element has been automatically removed.
Hierarchy of HashSet class:
The HashSet
class in Java is part of the Java Collections Framework, which is a set of interfaces and classes that provide implementations of commonly used data structures.
The HashSet
class is implemented as a hash table, which means that it stores elements in an unordered manner and provides constant-time performance for basic operations like adding, removing, and checking for the presence of an element.
Here is the hierarchy of the HashSet
class:
java.lang.Object java.util.AbstractCollection<E> java.util.AbstractSet<E> java.util.HashSet<E>
As you can see from the hierarchy, HashSet
is a subclass of AbstractSet
which is itself a subclass of AbstractCollection
. The AbstractSet
and AbstractCollection
classes provide some common functionality that can be used by all set and collection implementations.
The HashSet
class implements the Set
interface, which extends the Collection
interface. The Set
interface defines the basic operations that a set must support, such as adding, removing, and checking for the presence of an element. The Collection
interface provides additional methods for working with collections, such as iterating over the elements and finding the size of the collection.
Overall, the hierarchy of the HashSet
class shows how it is related to other classes and interfaces in the Java Collections Framework and provides a foundation for understanding how it works and how it can be used in Java programs.
HashSet class declaration:
Here is the declaration for the HashSet
class in Java:
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, Serializable { // Constructors public HashSet(); public HashSet(Collection<? extends E> c); public HashSet(int initialCapacity); public HashSet(int initialCapacity, float loadFactor); // Basic operations public boolean add(E e); public void clear(); public boolean contains(Object o); public boolean isEmpty(); public Iterator<E> iterator(); public boolean remove(Object o); public int size(); // Other methods public Object clone(); public boolean equals(Object o); public int hashCode(); public Spliterator<E> spliterator(); public Stream<E> stream(); public Stream<E> parallelStream(); public boolean removeAll(Collection<?> c); public boolean retainAll(Collection<?> c); public Object[] toArray(); public <T> T[] toArray(T[] a); }
The HashSet
class is a generic class, indicated by the <E>
type parameter. This means that you can create a HashSet
to hold any type of object by specifying the object’s type as the type parameter when you create the instance.
The HashSet
class extends the AbstractSet
class and implements the Set
interface, as well as the Cloneable
and Serializable
interfaces. This means that it inherits some basic set functionality from AbstractSet
and implements the required methods from the Set
interface.
The class provides several constructors, which allow you to create a HashSet
instance with or without specifying an initial capacity and load factor, as well as the option to create a HashSet
initialized with the elements of another collection.
The class also provides several methods for performing basic set operations, such as adding, removing, and checking for the presence of an element. In addition, it provides several other methods for working with sets, such as cloning the set, checking for equality with another object, and returning a Spliterator
or Stream
of the elements in the set.
Overall, the HashSet
class provides a powerful and flexible way to store and manipulate collections of unique elements in Java.
Constructors of Java HashSet class:
The HashSet
class in Java provides several constructors that allow you to create a new HashSet
instance with different options. Here are the available constructors:
HashSet()
: Creates an emptyHashSet
with the default initial capacity (16) and the default load factor (0.75).HashSet(Collection<? extends E> c)
: Creates aHashSet
initialized with the elements of the specified collectionc
. TheHashSet
is created with an initial capacity sufficient to hold the elements in the collection and the default load factor.HashSet(int initialCapacity)
: Creates an emptyHashSet
with the specified initial capacity and the default load factor.HashSet(int initialCapacity, float loadFactor)
: Creates an emptyHashSet
with the specified initial capacity and load factor.
The initialCapacity
parameter specifies the initial capacity of the HashSet
, which is the number of buckets in the hash table. The loadFactor
parameter specifies the load factor of the HashSet
, which is a measure of how full the hash table is allowed to get before it is resized.
The load factor is a float value between 0 and 1, and the default load factor is 0.75. A higher load factor means that the hash table can become more densely packed with elements before it is resized, which can improve performance, but also increases memory usage.
By default, HashSet
uses the hash code of the elements in the set to distribute them among the buckets in the hash table, but you can also provide your own implementation of the hashCode()
and equals()
methods for the elements in the set if necessary.
Methods of Java HashSet class:
The HashSet
class in Java provides several methods for performing various operations on the set. Here are some of the commonly used methods:
add(E e)
: Adds the specified elemente
to the set, if it is not already present. Returnstrue
if the element was added, orfalse
if it was already present.remove(Object o)
: Removes the specified elemento
from the set, if it is present. Returnstrue
if the element was removed, orfalse
if it was not present.contains(Object o)
: Returnstrue
if the set contains the specified elemento
, orfalse
if it does not.isEmpty()
: Returnstrue
if the set is empty, orfalse
if it contains one or more elements.size()
: Returns the number of elements in the set.clear()
: Removes all elements from the set.iterator()
: Returns an iterator over the elements in the set.toArray()
: Returns an array containing all the elements in the set, in no particular order.addAll(Collection<? extends E> c)
: Adds all the elements in the specified collectionc
to the set. Returnstrue
if the set was modified as a result of the operation.retainAll(Collection<?> c)
: Removes all elements from the set except those that are also in the specified collectionc
. Returnstrue
if the set was modified as a result of the operation.removeAll(Collection<?> c)
: Removes all elements from the set that are also in the specified collectionc
. Returnstrue
if the set was modified as a result of the operation.equals(Object o)
: Compares the specified objecto
with the set for equality. Returnstrue
if the object is a set with the same elements as the set, orfalse
otherwise.hashCode()
: Returns the hash code value for the set.spliterator()
: Returns aSpliterator
over the elements in the set.stream()
: Returns a sequentialStream
over the elements in the set.parallelStream()
: Returns a parallelStream
over the elements in the set.
Overall, the HashSet
class provides a comprehensive set of methods for working with sets of unique elements in Java.
Java HashSet Example:
Here’s an example of using the HashSet
class in Java:
import java.util.HashSet; public class HashSetExample { public static void main(String[] args) { // create a HashSet of strings HashSet<String> set = new HashSet<>(); // add elements to the set set.add("apple"); set.add("banana"); set.add("orange"); set.add("pear"); // print the set System.out.println("Set: " + set); // check if an element is present in the set System.out.println("Set contains 'banana': " + set.contains("banana")); // remove an element from the set set.remove("orange"); // print the set again System.out.println("Set after removing 'orange': " + set); // iterate over the elements in the set System.out.print("Set elements: "); for (String element : set) { System.out.print(element + " "); } System.out.println(); // clear the set set.clear(); // check if the set is empty System.out.println("Set is empty: " + set.isEmpty()); } }
Output:
Set: [pear, apple, orange, banana] Set contains 'banana': true Set after removing 'orange': [pear, apple, banana] Set elements: pear apple banana Set is empty: true
In this example, we first create a HashSet
of strings and add some elements to it. We then print the set, check if an element is present, remove an element, and iterate over the elements in the set.
Finally, we clear the set and check if it is empty.
Java HashSet example ignoring duplicate elements:
In Java, HashSet
does not allow duplicate elements. When you try to add a duplicate element, it will simply ignore it and not add it to the set. Here’s an example to demonstrate this behavior:
import java.util.HashSet; public class HashSetExample { public static void main(String[] args) { // create a HashSet of integers HashSet<Integer> set = new HashSet<>(); // add some elements to the set set.add(10); set.add(20); set.add(30); set.add(20); // this element will be ignored because it's a duplicate // print the set System.out.println("Set: " + set); } }
Output:
Set: [10, 20, 30]
In this example, we create a HashSet
of integers and add some elements to it. Notice that we add the element 20
twice, but it only appears once in the output because HashSet
ignores duplicates.
Java HashSet example to remove elements:
Here’s an example of how to remove elements from a HashSet
in Java:
import java.util.HashSet; public class HashSetExample { public static void main(String[] args) { // create a HashSet of strings HashSet<String> set = new HashSet<>(); // add some elements to the set set.add("apple"); set.add("banana"); set.add("orange"); set.add("pear"); // print the set System.out.println("Set: " + set); // remove an element from the set set.remove("banana"); // print the set again System.out.println("Set after removing 'banana': " + set); // remove all elements that contain the letter 'p' set.removeIf(element -> element.contains("p")); // print the set again System.out.println("Set after removing elements with 'p': " + set); // clear the set set.clear(); // check if the set is empty System.out.println("Set is empty: " + set.isEmpty()); } }
Output:
Set: [pear, apple, orange, banana] Set after removing 'banana': [pear, apple, orange] Set after removing elements with 'p': [apple] Set is empty: true
In this example, we first create a HashSet
of strings and add some elements to it. We then remove the element "banana"
from the set using the remove()
method.
Next, we remove all elements from the set that contain the letter "p"
using the removeIf()
method and a lambda expression. The removeIf()
method removes all elements from the set that satisfy the given predicate.
Finally, we clear the set and check if it is empty using the clear()
and isEmpty()
methods.
Java HashSet from another Collection:
In Java, you can create a HashSet
from another collection using the HashSet(Collection<? extends E> c)
constructor. This constructor creates a new HashSet
containing all the elements in the specified collection. Here’s an example:
import java.util.ArrayList; import java.util.HashSet; public class HashSetExample { public static void main(String[] args) { // create an ArrayList of strings ArrayList<String> list = new ArrayList<>(); list.add("apple"); list.add("banana"); list.add("orange"); list.add("pear"); // create a HashSet from the ArrayList HashSet<String> set = new HashSet<>(list); // print the set System.out.println("Set: " + set); } }
Output:
Set: [orange, banana, apple, pear]
In this example, we first create an ArrayList
of strings and add some elements to it. We then create a HashSet
from the ArrayList
using the HashSet(Collection<? extends E> c)
constructor.
The resulting HashSet
contains all the elements from the original ArrayList
, but the order may be different because HashSet
does not guarantee the order of its elements.
Java HashSet Example: Book
Here’s an example of how to use a HashSet
to store a collection of Book
objects in Java:
import java.util.HashSet; public class HashSetExample { public static void main(String[] args) { // create some Book objects Book book1 = new Book("The Great Gatsby", "F. Scott Fitzgerald"); Book book2 = new Book("To Kill a Mockingbird", "Harper Lee"); Book book3 = new Book("1984", "George Orwell"); Book book4 = new Book("The Catcher in the Rye", "J.D. Salinger"); Book book5 = new Book("Pride and Prejudice", "Jane Austen"); // create a HashSet to store the books HashSet<Book> bookSet = new HashSet<>(); // add the books to the HashSet bookSet.add(book1); bookSet.add(book2); bookSet.add(book3); bookSet.add(book4); bookSet.add(book5); // print the HashSet System.out.println("Book Set: " + bookSet); // remove a book from the HashSet bookSet.remove(book4); // print the HashSet again System.out.println("Book Set after removing 'The Catcher in the Rye': " + bookSet); } } class Book { private String title; private String author; public Book(String title, String author) { this.title = title; this.author = author; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } @Override public String toString() { return "\"" + title + "\" by " + author; } @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof Book)) { return false; } Book other = (Book) obj; return this.title.equals(other.title) && this.author.equals(other.author); } @Override public int hashCode() { return title.hashCode() ^ author.hashCode(); } }
Output:
Book Set: ["1984" by George Orwell, "The Catcher in the Rye" by J.D. Salinger, "To Kill a Mockingbird" by Harper Lee, "The Great Gatsby" by F. Scott Fitzgerald, "Pride and Prejudice" by Jane Austen] Book Set after removing 'The Catcher in the Rye': ["1984" by George Orwell, "To Kill a Mockingbird" by Harper Lee, "The Great Gatsby" by F. Scott Fitzgerald, "Pride and Prejudice" by Jane Austen]
In this example, we create some Book
objects and add them to a HashSet
using the add()
method. We then print the HashSet
.
Next, we remove a book from the HashSet
using the remove()
method. We then print the HashSet
again to confirm that the book was removed.
Note that the Book
class overrides the equals()
and hashCode()
methods to ensure that two Book
objects with the same title and author are considered equal, and that their hash codes are the same. This is necessary for the HashSet
to work correctly.