简体   繁体   English

带有自定义比较器的TreeSet无法产生正确的结果

[英]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 . 问题:给定一个String array ,删除重复项,并给出按String的长度排序的TreeSet。

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 当我得到正确的排序顺序时,我看到最终集中缺少许多不重复的元素(例如b, 456

To get correct behavior you need the the comparator output to agree with the equals method. 为了获得正确的行为,您需要比较器输出与equals方法一致。 Here your comparator has output 0 when two strings have the same length, so you only retain one element of each distinct length. 这里,当两个字符串的长度相同时,比较器的输出为0,因此,您只保留每个不同长度的一个元素。 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);
        }
    }

TreeMap considers equal all elements that compare to 0 (which is actually breaking the contract of Map interface). TreeMap认为等于0的所有元素均相等(这实际上违反了Map接口的协定)。 Therefore any same length Strings with your comparator will return 0 and be removed. 因此,与您的比较器相同长度的Strings将返回0并被删除。 You need to add a condition that if the Strings are same length, you should call the String's compareTo method. 您需要添加一个条件,如果字符串长度相同,则应调用字符串的compareTo方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM