Chapter 7 - Java for Beginners Course

Set and HashSet - Basic Operations

The last data structure we’ll cover in this chapter is HashSet, a concrete implementation of the Set interface.

The Set interface in Java is a Collection that is modelled after the mathematical concept of a set. They are collections of elements that don’t allow duplicate entries.

In this section we’ll cover some of the basic operations offered by the Set interface using HashSet as the concrete implementation for the examples.

Another common implementation of Set<E> is TreeSet<E> which we’ll not cover in this beginners course.
In the example code run the JavaBasicHashSetApp

Creating a HashSet

Let’s create a HashSet that will hold a set of numbers to show some of the properties of this data structure:

Set<Integer> numbers = new HashSet<>();
System.out.println("Initial size of the set: " + numbers.size());

Output:

Initial size of the set: 0

Adding elements

To add elements to a Set<E> we use the add(E element) method in the same way we did in the ArrayList section. For example, to add the number 10 we’d do:

numbers.add(10);
System.out.println("New size of the set: " + numbers.size());

Output:

New size of the set: 1

The add method returns a boolean to indicate whether the element was added or not to the set.

For example, if we try to add the number 10 again to our set, we should get false as a result as the number already exists in our set (remember Set doesn’t allow duplicates):

boolean secondTenAdded = numbers.add(10);
System.out.println("Was the second 10 added?: " + secondTenAdded);
System.out.println("Size of the set after 2nd addition: " + numbers.size());

Output:

Was the second 10 added?: false
Size of the set after 2nd addition: 1

We can see that, as expected, the size of the set is still 1 after attempting to add the same element more than once.

For the purpose of this example, we’ll add a couple more numbers to our set:

numbers.add(20);
numbers.add(30);

Our set now contains the numbers 10, 20 and 30.

Iterating over elements

To iterate over the elements of a set we can use an enhanced-for loop, for example, if we want to print out all the numbers in our example set, we could do the following:

for (Integer number : numbers) {
    System.out.println("Number in set: " + number);
}

Output:

Number in set: 20
Number in set: 10
Number in set: 30
Note that the ordering of the output isn’t the same as the order in which the elements were inserted. This is because HashSet doesn’t provide a sense of ordering of elements, in contrast to an ArrayList where each element can be identified by an index.
As discussed before, since Java 8 there are more ways of doing this. These will be covered in a later chapter after we introduce the concept of lambdas.

Checking if an element exists

In terms of performance, this is where a HashSet (and HashMap) excel as the lookup performance is of O(1) (beware of the notes mentioned in the hash tables section).

To check if an element already exists in the Set we make use of the contains(E element) method, for example, to check if numbers 10 and 15 already exist:

System.out.println("Number 10 exists in the set?: " + numbers.contains(10));
System.out.println("Number 15 exists in the set?: " + numbers.contains(15));

Output:

Number 10 exists in the set?: true
Number 15 exists in the set?: false

Removing an element

To remove an element from a Set (or a Collection in general), we make use of the remove(Object element) method. For example, to remove number 20 from our set we’d do the following:

numbers.remove(20);

Now, if we check if the set contains that number, we should get false as expected:

System.out.println("Number 20 exists in the set?: " + numbers.contains(20));

Output:

Number 20 exists in the set?: false

Other notes on HashSet

  1. The HashSet implementation uses the same theory explained in the hash tables section. Bear in mind the hashCode and equals methods when using hash-based set implementations.

  2. Behind the scenes, HashSet uses a HashMap to store its data.

Code in GitHub

Get the code for this tutorial using the links below.

Project Repo
Download code for this step
Main class for this step
Dependencies

This is a list of recommended tutorials or courses that might be useful before starting this one.

Contents
Welcome to the Course!
Course Introduction
Chapter 1 - Building Blocks
Quick introduction to Java Variables Classes And Objects Class Example - Defining a class Object Examples - Creating instances Java Application Example - Running our first app Accessing class members - The dot operator Packages - Organizing the code
Chapter 2 - Primitives and Operators
Primitives Arithmetic Operators Assignment Operator Unary Operators Equality and Relational Operators Conditional Operators
Chapter 3 - Statements and Control Flow
Expressions Statements If-Then Statement If-Then-Else Statement More If Statements Switch Statement While and Do-While Statements For Statement Branching Statements Exception Handling
Chapter 4 - Code Example
Example Project - A Simple Vending Machine Adding money Delivering Items Giving Change
Chapter 5 - Classes and Interfaces
Introduction Access Level Modifiers Class Declaration - Class, Methods and Fields Class Declaration - Constructors Inheritance Basics Inheritance - Constructors Inheritance - Methods and Fields Polymorphism Abstract Classes and Methods Interfaces Static Class Members Class Composition Final Classes and Class Members Generic Classes
Chapter 6 - Base Object Behaviors
Introduction Type Comparison Type Casting Object Equality - The Contract Object Equality - Common Pitfalls Object String Representation Garbage Collection Object Comparison Primitive Wrappers and Autoboxing
Chapter 7 - Data Structures
Introduction Arrays - Declaration and Creation Arrays - Basic Operations Core Collection Interfaces List and ArrayList - Basic Operations ArrayList Internals Introduction to Hash Tables Map and HashMap - Basic Operations Set and HashSet - Basic Operations
Chapter 8 - Anonymous classes and lambdas
Introduction Filtering a List Anonymous Classes Lambdas Built-in Functional Interfaces
Chapter 9 - Streams
Introduction Creating Streams Intermediate Operations Terminal Operations