Sorted set interface
The Java Collections Framework offers the SortedSet interface, which extends the Set interface and adds functionalities specific to maintaining a collection of elements in sorted order. This interface ensures that elements are stored and iterated through based on their natural ordering or a provided comparator.
Characteristics of SortedSet
⮚
Unique elements: Like Set, it stores unique elements, meaning duplicates are not allowed.
⮚
Ordered: Elements are maintained in a specific order. This order is determined by either the elements' natural ordering (if they implement Comparable) or a custom comparator provided during set creation.
⮚
Navigable: Most SortedSet implementations, like TreeSet, are also navigable. This means they offer additional methods for efficiently navigating through the sorted elements.
Common Implementations of SortedSet
TreeSet: The primary implementation of SortedSet. It uses a self-balancing tree structure (typically a red-black tree) to efficiently store and retrieve elements in sorted order. It relies on the elements' natural ordering (if they implement Comparable) or a custom comparator for sorting.
Initializing and Declaring SortedSet (Using TreeSet):
Declaration
Declaration syntax
SortedSet<DataType> setName;
Explanation
SortedSet: This specifies the interface you're using.
<DataType>: Placeholder for the data type the set will store. This data type must be comparable (implement the Comparable interface) or you need to provide a custom comparator during creation.
setName: The name for your reference variable.
Initialization
Creating an empty SortedSet (using TreeSet):
Creating an empty SortedSet
SortedSet<String> fruits = new TreeSet<>();
Note: In this case, elements must be comparable (e.g., String implements Comparable).
Creating a SortedSet with initial elements (Collection initializer - using TreeSet):
Creating SortedSet with initial elements
SortedSet<Integer> numbers = new TreeSet<>() {{
add(10);
add(20);
add(35);
}};
Note: Here, Integer implements Comparable, so it works inherently.
Methods of the SortedSet Interface (In addition to methods from Set):
⯌
comparator(): Returns the comparator used to order the elements in the set, or null if the natural ordering is used.
⯌
first(): Returns the first (smallest) element from the set according to the sorting order. Throws a NoSuchElementException if the set is empty.
⯌
last(): Returns the last (largest) element from the set according to the sorting order. Throws a NoSuchElementException if the set is empty.
⯌
headSet(E toElement): Returns a view of the portion of this set whose elements are strictly less than the toElement.
⯌
tailSet(E fromElement): Returns a view of the portion of this set whose elements are greater than or equal to the fromElement.
⯌
subSet(E fromElement, E toElement): Returns a view of the portion of this set whose elements range from fromElement (inclusive) to toElement (exclusive).
Example: Using TreeSet:
SortedSet simple example using treeset
import java.util.SortedSet;
import java.util.TreeSet;
public class Main {
public static void main(String[] args) {
// Create a TreeSet for numbers
SortedSet<Integer> numbers = new TreeSet<>();
numbers.add(5);
numbers.add(2);
numbers.add(8);
numbers.add(3); // Duplicate will not be added
// Print elements in sorted order (ascending)
System.out.println("Sorted elements: " + numbers);
// Get first and last elements
Integer firstNumber = numbers.first();
Integer lastNumber = numbers.last();
System.out.println("First number: " + firstNumber);
System.out.println("Last number: " + lastNumber);
}
}
Output
Sorted elements: [2, 3, 5, 8]
First number: 2
Last number: 8
Explanation : This example demonstrates adding elements to a TreeSet, iterating through them in sorted order, and retrieving the first and last elements based on the sorting order.
Custom Comparator for SortedSet:
If you want to sort elements based on a criteria different from their natural ordering, you can provide a custom comparator during creation of a TreeSet (which implements SortedSet):
SortedSet example using custom comparator
import java.util.*;
class Product {
int id;
String name;
double price;
public Product(int id, String name, double price) {
this.id = id;
this.name = name;
this.price = price;
}
}
public class Main {
public static void main(String[] args) {
Comparator<Product> comparator = new Comparator<Product>() {
@Override
public int compare(Product p1, Product p2) {
return p1.name.compareTo(p2.name); // Sort by name
}
};
SortedSet<Product> products = new TreeSet<>(comparator);
products.add(new Product(1, "Laptop", 599.99));
products.add(new Product(2, "Headphones", 79.95));
products.add(new Product(3, "Monitor", 199.99));
for (Product product : products) {
System.out.println("ID: " + product.id + ", Name: " + product.name + ", Price: $" + product.price);
}
}
}
Output
ID: 2, Name: Headphones, Price: $79.95
ID: 1, Name: Laptop, Price: $599.99
ID: 3, Name: Monitor, Price: $199.99
In this example, a custom comparator is created to sort Product objects based on their name.