Understanding TreeSet when compareto returns 0

后端 未结 5 783
逝去的感伤
逝去的感伤 2021-01-06 02:30

I have created a Student class like this:

public class Student implements Comparable {

    private String firstName;
    private String lastN         


        
5条回答
  •  不知归路
    2021-01-06 03:13

    Although question is quite old, but here is one very important point to understand which most people ignores while implementation.

    TreeSet does not compare the new element with all the existing elements in the Set. It uses binary search technique. Therefore, If your input element is equal to an existing element (as per compareTo contract) and same lies on the left side of tree and your compareTo method is implemented such a way that it forces your new element to lie on right side of tree, your TreeSet will not reject the new element even though same element is present inside it already (as per compareTo contract). Lets see the following simple example.

    I need to sort Items having properties as key and priority.

    package com.manish;
    import java.util.TreeSet;
    public class Main {
        static class Item implements Comparable {
            private long key;
            private int priority;
            public Item(long key, int priority) {
                super();
                this.key = key;
                this.priority = priority;
            }
    
            /*
             * Items should be treated equal if Keys are equal.
             * Higher priority item should be treated as greater item.
             * If priorities are same, lower key value item should be
             * treated as greater item.
             */
            @Override
            public int compareTo(Item o) {
                if (this.key == o.key) {
                    return 0;
                }
                if (this.priority != o.priority) {
                    return this.priority - o.priority;
                } else {
                    return this.key < o.key ? 1 : -1;
                }
            }
            @Override
            public String toString() {
                return "Item [key=" + key + ", priority=" + priority + "]";
            }
        }
        public static void main(String[] args) {
            TreeSet set = new TreeSet<>();
            set.add(new Item(2, 1));
            set.add(new Item(4, 3));
            set.add(new Item(3, 1)); //line 1
            set.add(new Item(3, 2)); //line 2. Same item as Item(3,1)
            while (!set.isEmpty())
                System.out.println(set.pollFirst());
        }
    }
    

    Output:

    Item [key=3, priority=1]
    Item [key=2, priority=1]
    Item [key=3, priority=2]
    Item [key=4, priority=3]
    

    However, if you swap the line 1 and line 2 code, the output will get changed as below.

    Item [key=2, priority=1]
    Item [key=3, priority=2]
    Item [key=4, priority=3]
    

提交回复
热议问题