Skip to content
Laviyx Learn

Try

Java course menu

Java HashSet and TreeSet: Unique Elements, Set Operations and Sorted Sets

Learn Java sets: HashSet for fast unique elements, add returning false for duplicates, contains, removing duplicates from a list, union, intersection and difference with addAll, retainAll and removeAll, LinkedHashSet for insertion order, and TreeSet for sorted elements and range queries.

Intermediate9 min readUpdated
On this page

A set holds unique elements: adding something that is already present has no effect. Sets answer "have I seen this before?" instantly, and they are the easiest way to remove duplicates. Java's main implementations are HashSet (fast, no order), LinkedHashSet (keeps insertion order) and TreeSet (keeps elements sorted).

HashSet basics#

Java
import java.util.HashSet;
import java.util.Set;

public class Main {
    public static void main(String[] args) {
        Set<String> visited = new HashSet<>();

        System.out.println(visited.add("Pune"));    // true: new element
        System.out.println(visited.add("Delhi"));
        System.out.println(visited.add("Pune"));    // false: already present

        System.out.println(visited.size());
        System.out.println(visited.contains("Delhi") + " " + visited.contains("Goa"));

        visited.remove("Delhi");
        System.out.println(visited);
    }
}
Output
true
true
false
2
true false
[Pune]

add returns false for a duplicate, which makes duplicate detection a one-liner. contains, add and remove are O(1) on average, compared with O(n) for List.contains.

Detecting and removing duplicates#

Java
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

public class Main {
    public static void main(String[] args) {
        List<Integer> ids = List.of(104, 221, 357, 221, 489, 104);

        Set<Integer> seen = new HashSet<>();
        for (int id : ids) {
            if (!seen.add(id)) {
                System.out.println("duplicate: " + id);
            }
        }

        List<Integer> unique = new ArrayList<>(new LinkedHashSet<>(ids));   // keeps first-seen order
        System.out.println(unique);
    }
}
Output
duplicate: 221
duplicate: 104
[104, 221, 357, 489]

A LinkedHashSet removes duplicates and keeps the original order. A plain HashSet would remove them too, but in an unspecified order.

Set operations#

Union, intersection and difference use the bulk methods. They modify the set they are called on, so work on a copy:

Java
import java.util.Set;
import java.util.TreeSet;

public class Main {
    public static void main(String[] args) {
        Set<String> chess = Set.of("Asha", "John", "Meera", "Ravi");
        Set<String> music = Set.of("John", "Kiran", "Meera", "Priya");

        Set<String> both = new TreeSet<>(chess);
        both.retainAll(music);           // intersection

        Set<String> either = new TreeSet<>(chess);
        either.addAll(music);            // union

        Set<String> onlyChess = new TreeSet<>(chess);
        onlyChess.removeAll(music);      // difference

        System.out.println(both);
        System.out.println(either);
        System.out.println(onlyChess);
    }
}
Output
[John, Meera]
[Asha, John, Kiran, Meera, Priya, Ravi]
[Asha, Ravi]

Using TreeSet copies here keeps the printed results in alphabetical order.

TreeSet: always sorted#

A TreeSet keeps its elements sorted, and offers ordered queries:

Java
import java.util.TreeSet;

public class Main {
    public static void main(String[] args) {
        TreeSet<Integer> slots = new TreeSet<>(java.util.List.of(16, 9, 14, 11));   // free hours

        System.out.println(slots);
        System.out.println(slots.first() + " " + slots.last());
        System.out.println("Next slot at or after 12: " + slots.ceiling(12));
        System.out.println("Latest slot before 12: " + slots.lower(12));
        System.out.println("Slots before noon: " + slots.headSet(12));
        System.out.println(slots.descendingSet());
    }
}
Output
[9, 11, 14, 16]
9 16
Next slot at or after 12: 14
Latest slot before 12: 11
Slots before noon: [9, 11]
[16, 14, 11, 9]
MethodReturns
first(), last()Smallest, largest
ceiling(x), floor(x)Smallest ≥ x, largest ≤ x
higher(x), lower(x)Smallest > x, largest < x
headSet(x), tailSet(x), subSet(a, b)Ranges

Operations are O(log n). Elements must be comparable (implement Comparable), or you pass a Comparator to the constructor; see Sorting.

Which set?#

HashSetLinkedHashSetTreeSet
OrderNoneInsertion orderSorted
add / containsO(1) averageO(1) averageO(log n)
Needsequals + hashCodeequals + hashCodecompareTo or a Comparator

Custom objects in sets#

HashSet decides "duplicate or not" with hashCode and equals. For your own classes, override both, or use a record, which generates them:

Java
import java.util.HashSet;
import java.util.Set;

record Point(int x, int y) {}

public class Main {
    public static void main(String[] args) {
        Set<Point> visited = new HashSet<>();
        visited.add(new Point(0, 0));
        visited.add(new Point(1, 2));
        visited.add(new Point(0, 0));   // equal record: not added again

        System.out.println(visited.size() + " " + visited.contains(new Point(1, 2)));
    }
}
Output
2 true

With a plain class that does not override equals and hashCode, each new Point(0, 0) would count as a different element.

Common mistakes#

Practice#

Practice exercise

From the text "the quick brown fox jumps over the lazy dog the end", print the distinct words in alphabetical order and how many there are.

Show solution
Java
import java.util.Arrays;
import java.util.Set;
import java.util.TreeSet;

public class DistinctWords {
    public static void main(String[] args) {
        String text = "the quick brown fox jumps over the lazy dog the end";
        Set<String> words = new TreeSet<>(Arrays.asList(text.split(" ")));
        System.out.println(words);
        System.out.println(words.size() + " distinct words");
    }
}
Output
[brown, dog, end, fox, jumps, lazy, over, quick, the]
9 distinct words

Key takeaway#

Finished this lesson?