Java Collections.checkedSortedSet Method
Last modified: April 20, 2025
The Collections.checkedSortedSet
method is part of Java's Collections
Framework. It provides runtime type safety for SortedSet implementations. This
method returns a dynamically type-safe view of the specified sorted set.
Any attempt to insert an element of the wrong type will result in an immediate
ClassCastException
. This helps detect programming errors early
rather than allowing them to propagate. The returned set will be serializable
if the specified set is serializable.
Collections.checkedSortedSet Overview
The checkedSortedSet
method is particularly useful when working
with legacy code or when type safety cannot be guaranteed at compile time. It
wraps an existing SortedSet and enforces type checking at runtime.
The method signature is: static <E> SortedSet<E>
checkedSortedSet(SortedSet<E> s, Class<E> type)
. It takes
the sorted set to wrap and the type of elements it should contain.
Basic Usage of checkedSortedSet
This example demonstrates the basic usage of Collections.checkedSortedSet
.
We create a TreeSet of Strings and wrap it with a type-safe view. The example
shows both valid and invalid operations.
package com.zetcode; import java.util.Collections; import java.util.SortedSet; import java.util.TreeSet; public class BasicCheckedSortedSet { public static void main(String[] args) { SortedSet<String> names = new TreeSet<>(); names.add("Alice"); names.add("Bob"); // Create type-safe view SortedSet<String> checkedNames = Collections.checkedSortedSet(names, String.class); // Valid operation checkedNames.add("Charlie"); System.out.println("Valid addition: " + checkedNames); try { // Invalid operation - adding wrong type checkedNames.add(42); // Integer instead of String } catch (ClassCastException e) { System.out.println("\nCaught exception: " + e.getMessage()); } } }
This code creates a TreeSet
of Strings and wraps it with
Collections.checkedSortedSet
. The type-safe view allows adding
valid String elements but throws ClassCastException
for invalid
types.
The output shows the successful addition of "Charlie" and the caught exception when trying to add an Integer. This demonstrates the runtime type checking.
Working with Legacy Code
The checkedSortedSet
is particularly useful when dealing with
legacy code that doesn't use generics. This example shows how to protect
against type-unsafe operations in such scenarios.
package com.zetcode; import java.util.Collections; import java.util.SortedSet; import java.util.TreeSet; public class LegacyCodeProtection { @SuppressWarnings({"unchecked", "rawtypes"}) public static void main(String[] args) { // Legacy code without generics SortedSet rawSet = new TreeSet(); rawSet.add("Apple"); rawSet.add("Banana"); // Create type-safe view SortedSet<String> safeSet = Collections.checkedSortedSet(rawSet, String.class); // Pass to legacy method legacyMethod(rawSet); System.out.println("After legacy method: " + safeSet); try { // Now try to use the safe view safeSet.add("Cherry"); // Valid safeSet.add(123); // Invalid } catch (ClassCastException e) { System.out.println("\nCaught exception: " + e.getMessage()); } } @SuppressWarnings("rawtypes") private static void legacyMethod(SortedSet set) { // Legacy method might add wrong types set.add(42); // This will succeed in raw set } }
This example demonstrates how checkedSortedSet
can help identify
type safety issues in legacy code. The raw set allows adding any type, but the
type-safe view catches invalid additions when used.
The output shows that the legacy method successfully added an Integer to the raw set, but attempting to add an Integer through the type-safe view throws an exception. This helps localize type safety issues.
Combining with Other Collections Methods
This example shows how checkedSortedSet
can be combined with other
Collections utility methods. We create an unmodifiable type-safe view of a
sorted set.
package com.zetcode; import java.util.Collections; import java.util.SortedSet; import java.util.TreeSet; public class CombinedCollectionsMethods { public static void main(String[] args) { SortedSet<Integer> numbers = new TreeSet<>(); numbers.add(10); numbers.add(20); numbers.add(30); // Create type-safe and unmodifiable view SortedSet<Integer> safeUnmodifiableSet = Collections.unmodifiableSortedSet( Collections.checkedSortedSet(numbers, Integer.class)); System.out.println("Initial set: " + safeUnmodifiableSet); try { // Attempt modification through unmodifiable view safeUnmodifiableSet.add(40); } catch (UnsupportedOperationException e) { System.out.println("\nCaught UnsupportedOperationException: " + e.getMessage()); } try { // Attempt to add wrong type to original set numbers.add("Not a number"); } catch (ClassCastException e) { System.out.println("\nCaught ClassCastException: " + e.getMessage()); } } }
This code combines checkedSortedSet
with
unmodifiableSortedSet
to create a view that is both type-safe and
unmodifiable. The example demonstrates both type safety and immutability
protection.
The output shows that attempts to modify the set through the unmodifiable view are caught, as are attempts to add elements of the wrong type to the original set. This demonstrates layered collection protections.
Using with Custom Comparators
The checkedSortedSet
works with sorted sets that use custom
comparators. This example demonstrates type checking in a sorted set with a
case-insensitive string comparator.
package com.zetcode; import java.util.Collections; import java.util.Comparator; import java.util.SortedSet; import java.util.TreeSet; public class CustomComparatorExample { public static void main(String[] args) { // Create sorted set with case-insensitive comparator SortedSet<String> caseInsensitiveSet = new TreeSet<>( String.CASE_INSENSITIVE_ORDER); caseInsensitiveSet.add("Apple"); caseInsensitiveSet.add("banana"); // Create type-safe view SortedSet<String> checkedSet = Collections.checkedSortedSet(caseInsensitiveSet, String.class); System.out.println("Original set: " + checkedSet); // Adding with different case works due to comparator checkedSet.add("APPLE"); System.out.println("After adding 'APPLE': " + checkedSet); try { // Adding wrong type fails checkedSet.add(42); } catch (ClassCastException e) { System.out.println("\nCaught ClassCastException: " + e.getMessage()); } } }
This example shows that checkedSortedSet
works with sorted sets
that use custom comparators. The type checking is performed independently of
the sorting logic.
The output demonstrates that the case-insensitive comparator allows "APPLE" to be added (though it doesn't appear twice due to being equal to "Apple"), while attempting to add an Integer is caught by the type checking.
Serialization with checkedSortedSet
The set returned by checkedSortedSet
is serializable if the
backing set is serializable. This example demonstrates serialization and
deserialization of a type-safe sorted set.
package com.zetcode; import java.io.*; import java.util.Collections; import java.util.SortedSet; import java.util.TreeSet; public class SerializationExample { public static void main(String[] args) { String filename = "checkedset.ser"; // Create and serialize a checked sorted set try (ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream(filename))) { SortedSet<Double> numbers = new TreeSet<>(); numbers.add(3.14); numbers.add(2.71); SortedSet<Double> checkedNumbers = Collections.checkedSortedSet(numbers, Double.class); oos.writeObject(checkedNumbers); System.out.println("Serialized set: " + checkedNumbers); } catch (IOException e) { e.printStackTrace(); } // Deserialize the checked sorted set try (ObjectInputStream ois = new ObjectInputStream( new FileInputStream(filename))) { @SuppressWarnings("unchecked") SortedSet<Double> deserialized = (SortedSet<Double>) ois.readObject(); System.out.println("Deserialized set: " + deserialized); // Verify type safety still works try { deserialized.add("Not a number"); } catch (ClassCastException e) { System.out.println("\nCaught ClassCastException: " + e.getMessage()); } } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } }
This example demonstrates that the type-safe wrapper maintains its type checking capabilities after serialization and deserialization. The serialized set preserves both its elements and its type safety constraints.
The output shows the set before serialization and after deserialization, followed by the caught exception when attempting to add an invalid type. This confirms that type safety is maintained through serialization.
Performance Considerations
While checkedSortedSet
provides valuable type safety, it does add
a small performance overhead. This example demonstrates how to measure the
impact of the type checking wrapper.
package com.zetcode; import java.util.Collections; import java.util.SortedSet; import java.util.TreeSet; public class PerformanceComparison { public static void main(String[] args) { final int ELEMENT_COUNT = 100000; final int TEST_RUNS = 100; SortedSet<Integer> regularSet = new TreeSet<>(); SortedSet<Integer> checkedSet = Collections.checkedSortedSet(new TreeSet<>(), Integer.class); // Test regular set performance long regularTime = timeAddOperations(regularSet, ELEMENT_COUNT, TEST_RUNS); // Test checked set performance long checkedTime = timeAddOperations(checkedSet, ELEMENT_COUNT, TEST_RUNS); System.out.println("Regular set time: " + regularTime + " ms"); System.out.println("Checked set time: " + checkedTime + " ms"); System.out.println("Overhead: " + ((double)(checkedTime - regularTime)/regularTime * 100) + "%"); } private static long timeAddOperations(SortedSet<Integer> set, int count, int runs) { long totalTime = 0; for (int i = 0; i < runs; i++) { set.clear(); long start = System.currentTimeMillis(); for (int j = 0; j < count; j++) { set.add(j); } totalTime += System.currentTimeMillis() - start; } return totalTime / runs; } }
This code compares the performance of a regular TreeSet
with a
type-safe wrapped version. The test measures the time taken to add elements
to both sets, averaging over multiple runs for accuracy.
The output shows the absolute times and the percentage overhead introduced by the type checking. While the overhead is typically small, it's important to consider in performance-critical applications.
Source
Java Collections.checkedSortedSet Documentation
In this article, we've explored the Collections.checkedSortedSet
method in depth. We've covered basic usage, legacy code integration, combination
with other utilities, custom comparators, serialization, and performance.
Author
List all Java tutorials.