简体   繁体   English

如何使用我的比较器对 TreeSet 中的重复项进行排序和避免重复?

[英]How to sort and avoid duplicates in TreeSet with my comparator?

I wan to create TreeSet() that will sort my elements with my predefined comparator.我想创建TreeSet() ,它将使用我预定义的比较器对我的元素进行排序。 But the problem is when I give the comparator as a parameter to the constructor of the TreeSet(MyComparator) , the TreeSet is not avoiding duplicates.但问题是,当我将比较器作为参数提供给TreeSet(MyComparator)的构造函数时,TreeSet 并没有避免重复。 Can I achieve sorting of the elements and avoiding duplicates?我可以实现元素的排序并避免重复吗?

The comparator looks like:比较器看起来像:

public static Comparator<Participant> byNameAndAge = (L, R) -> {
    //check if they have the same code
    if (L.code.equalsIgnoreCase(R.code))
        return 0;

    int res = L.name.compareToIgnoreCase(R.name);
    if (res == 0)
        res = Integer.compare(L.age, R.age);
    return res;
};

You've misunderstood a few things.你误解了一些事情。 TreeSet does eliminate duplicates, with 'a duplicate' defined as 'any two elements for which your compare method returns 0'. TreeSet 确实消除了重复项,“重复项”定义为“比较方法返回 0 的任何两个元素”。 No 2 such elements can both exist in a treeset.没有 2 个这样的元素可以同时存在于树集中。 I'm sure your code doesn't work if you say so, but the code you pasted isn't the problem, nor is TreeSet's code.如果您这么说,我确定您的代码不起作用,但是您粘贴的代码不是问题,TreeSet 的代码也不是。

A trivial example:一个简单的例子:

Comparator<String> byLength = (a, b) -> a.length() - b.length();
Set<String> set = new TreeSet<String>(byLength);
set.add("Hello");
set.add("World");
set.add("X");
set.add("VeryLong");
System.out.println(set);

> [X, Hello, VeryLong]

Note how 'World' disappeared, because the comparator says it is equal to Hello (they are both 5 length, a.length() - b.length() is returning 0, and 0 is 'equal, thus, eliminate the duplicate' according to treeset).请注意“世界”是如何消失的,因为比较器说它等于 Hello(它们都是 5 长度,a.length() - b.length() 返回 0,而 0 是“相等,因此,消除重复”根据树集)。 In other words, your code as pasted would eliminate duplicates, the problem lies elsewhere.换句话说,您粘贴的代码消除重复,问题出在其他地方。

This code is almost the same as yours.此代码与您的代码几乎相同。


Comparators chaining比较器链接

public static void main(String[] args) {
    // custom comparator
    Comparator<Participant> byNameAndAge = Comparator
            // first sorting by name ignoring case
            .comparing(Participant::getName, String::compareToIgnoreCase)
            // second sorting by age
            .thenComparingInt(Participant::getAge);

    // constructor with a comparator as a parameter
    TreeSet<Participant> treeSet = new TreeSet<>(byNameAndAge);
    treeSet.addAll(Set.of( // test data
            new Participant("John", 25),
            new Participant("Junior", 2),
            new Participant("james", 31),
            new Participant("john", 22)));

    // output
    treeSet.forEach(System.out::println);
    //name=james, age=31
    //name=john, age=22
    //name=John, age=25
    //name=Junior, age=2
}
static class Participant {
    String name;
    int age;

    public Participant(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() { return name; }
    public int getAge() { return age; }

    @Override
    public String toString() {
        return "name=" + name + ", age=" + age;
    }
}

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

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