A Comparator defines an ordering relation; sorted collections use a zero comparison to decide that two keys occupy one ordering position.
Java comparators: tie-breakers, overflow and sorted-key identity
Java 8+. This is a complete program using JDK classes.
Preserve distinct jobs
A dispatch comparator that compares only priority merges two distinct jobs at the same priority when used in a TreeSet. Sorting a list preserves both values, but the sorted set interprets equality under the comparator as one membership slot. The same comparator can therefore have different consequences depending on its consumer.
Use a stable identifier as a tie-breaker when both jobs must remain. The identifier must itself have a total order and a defined duplicate policy. A changing priority field makes a mutable key dangerous after insertion; a sorted structure does not continuously rebuild its internal path when a field changes.
Do not compare integer priorities by subtraction. Extreme inputs can overflow and reverse the intended sign. Comparator.comparingInt, Integer.compare and explicit thenComparing steps state the policy without relying on a difference fitting in int.
Test the relation
Check equal values, reverse pairs and triples when reviewing a custom comparator. Inconsistent or non-transitive results can invalidate sorted algorithms. The program deliberately compares the broken policy with an identifier-aware policy so the lost member is visible without a timing measurement.
Working program
import java.util.Comparator;
import java.util.TreeSet;
public class DispatchJobOrdering {
static final class Job {
final String id; final int priority;
Job(String id, int priority) { this.id=id; this.priority=priority; }
}
public static void main(String[] args) {
Comparator<Job> priorityOnly = Comparator.comparingInt(job -> job.priority);
TreeSet<Job> merged = new TreeSet<>(priorityOnly);
merged.add(new Job("D-11", 3)); merged.add(new Job("D-12", 3));
TreeSet<Job> distinct = new TreeSet<>(priorityOnly.thenComparing(job -> job.id));
distinct.addAll(merged); distinct.add(new Job("D-12", 3));
System.out.println(merged.size());
System.out.println(distinct.size());
System.out.println(Integer.compare(Integer.MIN_VALUE, Integer.MAX_VALUE));
}
}Output
1
2
-1Costs and boundaries
Each TreeSet insertion uses O(log n) comparisons. The comparator may add string comparison work proportional to a differing prefix; O(log n) does not mean character work disappears. Membership storage is O(n).
Common Mistakes
- A priority tie is not necessarily object equality.
- Changing a comparison field after insertion can corrupt lookup assumptions.
- Subtracting two int values can overflow.
Read next
Set equivalence, Comparator sorting.
Continue with the new boundary checks
Continue with Java LinkedList sort: stable order needs temporary array work.
