简体   繁体   English

为什么使用自定义Comparator到treeSet破坏了String对象的相等性?

[英]Why using custom Comparator to treeSet is breaking the equality of String objects?

I have written a comparator which is calculating consonants in a given string to compare 2 strings, but it is somehow making TreeSet think that 2 strings are equal (may be when they are of same size). 我编写了一个比较器,该比较器在给定的字符串中计算辅音以比较2个字符串,但是以某种方式使TreeSet认为2个字符串相等(可能是它们的大小相同)。

public class SortDiff {
public static void main(String[] s1) {

    List<String> list = Arrays.asList("century", "army", "spit", "twin", "frog", "guideline", "impulse",
            "distributor", "hallway", "appeal", "fitness", "pudding", "mild", "enter", "kitchen", "constitutional",
            "die", "condition", "morsel", "jealous", "colorful", "myth", "belly", "rugby", "valid", "shot",
            "locate", "preference", "representative", "chart", "prince", "think", "threshold", "health", "sweater",
            "volume", "poison", "lease", "toast", "diplomat", "trait", "cower", "slime", "handy", "example",
            "sanctuary", "board", "crash", "large", "attract", "censorship", "room", "license", "smoke", "roll",
            "taste", "inflate", "continuation", "establish", "fault", "gown", "dirty", "width", "qualify",
            "reference", "excitement", "vegetable", "wear", "confusion", "concept", "willpower", "snarl", "develop",
            "integration", "pie", "respectable", "fast", "limit", "shaft", "acceptance", "insert", "brown", "death",
            "effective", "ticket", "play", "highway", "lot", "tablet", "mother", "pier", "facility", "match",
            "animal", "sport", "laundry", "negligence", "white", "vat", "nuclear");
    System.out.println(list.size() + "=====");
    TreeSet<String> tree = new TreeSet<String>(new sortByConsonants());//
    int count = 0;
    for (String s : list) {
        count++;
        System.out.println(s);
        System.out.println(tree.add(s));
    }
    System.out.println("===>" + count);
    System.out.println(tree.size() + "=====");
    Iterator itr = tree.iterator();
    while (itr.hasNext()) {
        System.out.println(itr.next());
    }
}


}

This is the comparator class which I am passing to TreeSet. 这是我传递给TreeSet的比较器类。

class sortByConsonants implements Comparator<String>{

    public int compare(String a, String b) 
    { 

        return count(a,2)-count(b,2);
    } 
    public boolean equals(String a,String b) {

        return a.equals(b);

    }

    public int count(String line,int type) {
        int vowels = 0, consonants = 0, digits = 0, spaces = 0;

        line = line.toLowerCase();
        for(int i = 0; i < line.length(); ++i)
        {
            char ch = line.charAt(i);
            if(ch == 'a' || ch == 'e' || ch == 'i'
                || ch == 'o' || ch == 'u') {
                ++vowels;
            }
            else if((ch >= 'a'&& ch <= 'z')) {
                ++consonants;
            }
            else if( ch >= '0' && ch <= '9')
            {
                ++digits;
            }
            else if (ch ==' ')
            {
                ++spaces;
            }
        }

        if(type==1) {
            return vowels;
        }else {
            return consonants;
        }

    }

}

Can someone please look into it and find what mistake I am making!! 有人可以调查一下,找出我犯的错误!!

Goal : I want to sort strings based on count of consonants (Without use of library sort() method) 目标:我想根据辅音的数量对字符串排序(不使用库sort()方法)

Edit : changed to comparator logic to 编辑:更改为比较器逻辑

public int compare(String a, String b) 
    { 
        if(count(a,2)-count(b,2)==0) {
            return 1;
        }
        return count(a,2)-count(b,2);
    } 

Still not working!! 还是行不通!!

Edit = For this question TreeSet is not the right Data Structure, should use ArrayList. 编辑=对于此问题TreeSet不是正确的数据结构,应使用ArrayList。

Change your SortByConsonants to the following. 将您的SortByConsonants更改为以下内容。 (Note that class names should start with a capital letter) (请注意,班级名称应以大写字母开头)

class SortByConsonants implements Comparator<String> {

    public int compare(String a, String b) {
        if (count(a) - count(b) == 0) {
            return 1;
        }
        return count(a) - count(b);
    }

    public boolean equals(String a, String b) {
        return a.equals(b);
    }

    public int count(String line) {
        int consonants = 0;
        line = line.toLowerCase();
        for (int i = 0; i < line.length(); ++i) {
            char ch = line.charAt(i);
            if (ch != 'a' && ch != 'e' && ch != 'i' && ch != 'o' && ch != 'u') {
                consonants++;
            }
        }
        return consonants;
    }

}

Also, since we are just interested to sort based on the count of consonants there is no need to calculate the number of vowels, spaces, digits, etc. Furthermore, there is also no need of passing in another parameter type to the method count 同样,由于我们只是想根据辅音的数量进行排序,因此无需计算元音,空格,数字等的数量。此外,也无需将其他参数类型传递给方法count

Your comperator as you coded it, will return 0 (meaning equality) 您编写的编译器将返回0 (表示相等)
if 2 strings have the same number of consonants . 如果2个弦的辅音数量相同
You defined: 您定义了:

TreeSet<String> tree = new TreeSet<String>(new sortByConsonants());

so in tree there can't exist 2 items (strings) with the same number of consonants 所以在tree中不能存在两个具有相同辅音数量的项目(字符串)

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

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