eagertoLearn
eagertoLearn

Reputation: 10162

TreeSet with custom comparator is not producing correct results

I am not able to figure out what could be the error. It could be a silly one.

Question: given an array of String, remove duplicates and give TreeSet that is sorted by the length of the String.

Here is my implementation:

public class MyPrograms {

public static void main(String[] args){
        String[] arr = {"hello","world","a","b","cv","def","456","hello","world","b"};
        System.out.println(Arrays.toString(arr));
        sortStringbyLen(arr);
    }

public static void sortStringbyLen(String[] arr){


        Set<String> set = new TreeSet<String>(new Comparator<String>(){

            @Override
            public int compare(String o1, String o2) {
                return Integer.compare(o2.length(), o1.length());
            }
        });
        set.addAll(Arrays.asList(arr));
        System.out.println(set);
    }
}
}

The output is:

[hello, world, a, b, cv, def, 456, hello, world, b]
[hello, def, cv, a]

while I get the sorting order correct, I see many non-duplicate elements (such as b, 456) missing in the final set

Upvotes: 0

Views: 100

Answers (2)

jonderry
jonderry

Reputation: 23643

To get correct behavior you need the the comparator output to agree with the equals method. Here your comparator has output 0 when two strings have the same length, so you only retain one element of each distinct length. To fix it, you should break ties in your comparator, perhaps like this:

    new Comparator<String>(){

        @Override
        public int compare(String o1, String o2) {
            int cmp = Integer.compare(o2.length(), o1.length());
            return cmp != 0 ? cmp : o1.compareTo(o2);
        }
    }

Upvotes: 2

Kayaman
Kayaman

Reputation: 73578

TreeMap considers equal all elements that compare to 0 (which is actually breaking the contract of Map interface). Therefore any same length Strings with your comparator will return 0 and be removed. You need to add a condition that if the Strings are same length, you should call the String's compareTo method.

Upvotes: 1

Related Questions