Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java TreeSet comparator collisions: compare zero means one slot

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

TreeSet uses comparator equality to decide whether a candidate is already present, even when the objects have different identifiers.

A lossy comparator drops work

Two review jobs share priority one but have different receipt IDs. A TreeSet ordered only by priority rejects the second job. A comparator with receipt ID as a tie-breaker retains both. The program prints sizes, avoiding any dependence on a representation order for the rejected set.

This is a data-loss boundary. If two distinct business objects may compare as zero, a sorted set is not a safe queue until the comparator defines their identity. PriorityQueue tie order has a different contract: a priority queue can hold equivalent-ranked jobs, but their removal order is unspecified.

Use an ordering that matches the key model

A comparator must be transitive. Subtraction is a poor shortcut when integer overflow is possible. If equality and ordering describe different concepts, use a list or a map keyed by explicit ID instead of forcing both into one TreeSet.

Working program

Java
import java.util.Comparator;
import java.util.TreeSet;
public class ReviewJobSet {
    static final class Job {
        final String receiptId; final int priority;
        Job(String receiptId, int priority) { this.receiptId = receiptId; this.priority = priority; }
    }
    public static void main(String[] args) {
        Job east = new Job("R-41", 1);
        Job west = new Job("R-42", 1);
        TreeSet<Job> lossy = new TreeSet<>(Comparator.comparingInt(job -> job.priority));
        lossy.add(east);
        System.out.println("second accepted=" + lossy.add(west));
        TreeSet<Job> complete = new TreeSet<>(Comparator.comparingInt((Job job) -> job.priority)
            .thenComparing(job -> job.receiptId));
        complete.add(east); complete.add(west);
        System.out.println("lossy=" + lossy.size() + ", complete=" + complete.size());
    }
}

Output

Output
second accepted=false
lossy=1, complete=2

Costs and boundaries

TreeSet offers logarithmic add and lookup in its element count when the comparator behaves correctly. The example proves a collision, not a performance advantage over a hash-based set.

Common Mistakes

  • Do not use a partial comparator as a business identity rule.
  • Do not assume object equals controls TreeSet uniqueness.
  • Do not subtract priorities if overflow is possible.

Read next

Java LinkedHashSet and TreeSet: order and uniqueness, Java comparators: tie-breakers, overflow and sorted-key identity, Java PriorityQueue: define tie order in the comparator.

java
treeset-comparator-collision
Storage details