This rule raises an issue when a sorted collection relies on natural ordering, but its element or key type does not implement a compatible Comparable interface. Provide an explicit Comparator or define a natural ordering for the type.

Why is this an issue?

Sorted collections need an ordering to compare their elements or keys. They can use either the natural ordering defined by Comparable or an explicit Comparator.

When a collection relies on natural ordering, every element or key must implement a compatible Comparable interface. Otherwise, operations that compare values can throw a ClassCastException at runtime.

How to fix it

Provide a comparator when the element or key type does not have a natural ordering. Alternatively, implement Comparable on the type when it has a single meaningful natural ordering.

Code examples

When the type has no natural ordering, construct the collection with an explicit comparator.

Noncompliant code example

class Task {
  int priority;
}

Set<Task> tasks = new TreeSet<>(); // Noncompliant
Map<Task, String> assignments = new TreeMap<>(); // Noncompliant
Queue<Task> pendingTasks = new PriorityQueue<>(); // Noncompliant
Set<Task> concurrentTasks = new ConcurrentSkipListSet<>(); // Noncompliant
Map<Task, String> concurrentAssignments = new ConcurrentSkipListMap<>(); // Noncompliant

Compliant solution

class Task {
  int priority;
}

Comparator<Task> byPriority = Comparator.comparingInt(task -> task.priority);

Set<Task> tasks = new TreeSet<>(byPriority);
Map<Task, String> assignments = new TreeMap<>(byPriority);
Queue<Task> pendingTasks = new PriorityQueue<>(byPriority);
Set<Task> concurrentTasks = new ConcurrentSkipListSet<>(byPriority);
Map<Task, String> concurrentAssignments = new ConcurrentSkipListMap<>(byPriority);

When the type has a single meaningful natural ordering, implement Comparable on that type.

Noncompliant code example

class Task {
  int priority;
}

Queue<Task> tasks = new PriorityQueue<>(); // Noncompliant

Compliant solution

class Task implements Comparable<Task> {
  int priority;

  @Override
  public int compareTo(Task other) {
    return Integer.compare(priority, other.priority);
  }
}

Queue<Task> tasks = new PriorityQueue<>();

Resources

Documentation