Java SortedSet Interface

Introduction

The SortedSet interface in Java, part of the java.util package, represents a set that maintains its elements in ascending order. This interface extends the Set interface and provides methods for navigation and retrieving subsets. The most commonly used implementation of SortedSet is TreeSet.

Table of Contents

  1. What is the SortedSet Interface?
  2. Common Implementations
  3. Common Methods
  4. Examples of Using the SortedSet Interface
  5. Conclusion

1. What is the SortedSet Interface?

The SortedSet interface extends the Set interface and maintains its elements sorted according to their natural ordering or by a specified comparator. This ordering is consistent with equals only if the comparator used is consistent with equals.

2. Common Implementations

  • TreeSet: A Red-Black tree-based implementation of the SortedSet interface. It provides guaranteed log(n) time cost for the basic operations (add, remove, contains) and maintains the order of its elements.

3. Common Methods

  • comparator(): Returns the comparator used to order the elements in this set, or null if this set uses the natural ordering of its elements.
  • subSet(E fromElement, E toElement): Returns a view of the portion of this set whose elements range from fromElement, inclusive, to toElement, exclusive.
  • headSet(E toElement): Returns a view of the portion of this set whose elements are strictly less than toElement.
  • tailSet(E fromElement): Returns a view of the portion of this set whose elements are greater than or equal to fromElement.
  • first(): Returns the first (lowest) element currently in this set.
  • last(): Returns the last (highest) element currently in this set.

4. Examples of Using the SortedSet Interface

Example 1: Basic Usage with TreeSet

This example demonstrates how to use a TreeSet with the SortedSet interface.

import java.util.SortedSet;
import java.util.TreeSet;

public class SortedSetExample {
    public static void main(String[] args) {
        SortedSet<String> set = new TreeSet<>();

        // Adding elements to the set
        set.add("Banana");
        set.add("Apple");
        set.add("Cherry");
        set.add("Date");

        // Displaying the set
        System.out.println("SortedSet: " + set);

        // Accessing the first and last elements
        System.out.println("First Element: " + set.first());
        System.out.println("Last Element: " + set.last());

        // Getting a subSet
        SortedSet<String> subSet = set.subSet("Banana", "Date");
        System.out.println("SubSet from Banana to Date: " + subSet);

        // Getting a headSet
        SortedSet<String> headSet = set.headSet("Cherry");
        System.out.println("HeadSet up to Cherry: " + headSet);

        // Getting a tailSet
        SortedSet<String> tailSet = set.tailSet("Cherry");
        System.out.println("TailSet from Cherry: " + tailSet);
    }
}

Output:

SortedSet: [Apple, Banana, Cherry, Date]
First Element: Apple
Last Element: Date
SubSet from Banana to Date: [Banana, Cherry]
HeadSet up to Cherry: [Apple, Banana]
TailSet from Cherry: [Cherry, Date]

Example 2: Using Custom Comparator

This example shows how to use a TreeSet with a custom comparator.

import java.util.Comparator;
import java.util.SortedSet;
import java.util.TreeSet;

public class CustomComparatorExample {
    public static void main(String[] args) {
        Comparator<String> reverseOrder = Comparator.reverseOrder();
        SortedSet<String> set = new TreeSet<>(reverseOrder);

        // Adding elements to the set
        set.add("Banana");
        set.add("Apple");
        set.add("Cherry");

        // Displaying the set
        System.out.println("SortedSet with Custom Comparator: " + set);

        // Accessing the first and last elements
        System.out.println("First Element: " + set.first());
        System.out.println("Last Element: " + set.last());
    }
}

Output:

SortedSet with Custom Comparator: [Cherry, Banana, Apple]
First Element: Cherry
Last Element: Apple

Example 3: Navigating through the Set

This example demonstrates how to navigate through the SortedSet using different methods.

import java.util.SortedSet;
import java.util.TreeSet;

public class NavigationExample {
    public static void main(String[] args) {
        SortedSet<Integer> set = new TreeSet<>();

        // Adding elements to the set
        set.add(1);
        set.add(2);
        set.add(3);
        set.add(4);
        set.add(5);

        // Displaying the set
        System.out.println("SortedSet: " + set);

        // Accessing elements using navigational methods
        System.out.println("HeadSet (less than 3): " + set.headSet(3));
        System.out.println("TailSet (3 and more): " + set.tailSet(3));
        System.out.println("SubSet (2 to 4): " + set.subSet(2, 4));
    }
}

Output:

SortedSet: [1, 2, 3, 4, 5]
HeadSet (less than 3): [1, 2]
TailSet (3 and more): [3, 4, 5]
SubSet (2 to 4): [2, 3]

Example 4: Using SortedSet with Custom Objects

This example demonstrates how to use a SortedSet with custom objects, requiring the implementation of Comparable or providing a Comparator.

import java.util.Objects;
import java.util.SortedSet;
import java.util.TreeSet;

public class CustomObjectSortedSetExample {
    public static void main(String[] args) {
        SortedSet<Person> set = new TreeSet<>();

        // Adding custom objects to the set
        set.add(new Person("Raj", 30));
        set.add(new Person("Anita", 25));
        set.add(new Person("Vikram", 35));

        // Iterating over the set
        for (Person person : set) {
            System.out.println(person);
        }
    }
}

class Person implements Comparable<Person> {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public int compareTo(Person other) {
        return Integer.compare(this.age, other.age);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age && Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}

Output:

Person{name='Anita', age=25}
Person{name='Raj', age=30}
Person{name='Vikram', age=35}

5. Conclusion

The SortedSet interface in Java provides a powerful way to manage sets that maintain their elements in ascending order. By using different implementations like TreeSet, developers can take advantage of navigational methods and custom ordering. The examples provided demonstrate common usage patterns and highlight the capabilities of the SortedSet interface.

Comments