如何使用我的比较器对 TreeSet 进行排序和避免重复?
How to sort and avoid duplicates in TreeSet with my comparator?
我想创建 TreeSet()
来使用我预定义的比较器对我的元素进行排序。但问题是当我将比较器作为参数提供给 TreeSet(MyComparator)
的构造函数时,TreeSet 没有避免重复。能否实现元素的排序和避免重复?
比较器看起来像:
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;
};
你误解了一些事情。 TreeSet确实消除了重复,'a duplicate'定义为'any two elements for which your compare method returns 0'。树集中不能同时存在 2 个这样的元素。如果你这么说,我确定你的代码不起作用,但你粘贴的代码不是问题,TreeSet 的代码也不是。
一个简单的例子:
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]
注意 'World' 是如何消失的,因为比较器说它等于 Hello(它们都是 5 长度,a.length() - b.length() 返回 0,并且根据树集,0 是 'equal, thus, eliminate the duplicate')。换句话说,您粘贴的代码 会 消除重复项,问题出在其他地方。
这段代码和你的几乎一样。
比较器链接
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;
}
}
我想创建 TreeSet()
来使用我预定义的比较器对我的元素进行排序。但问题是当我将比较器作为参数提供给 TreeSet(MyComparator)
的构造函数时,TreeSet 没有避免重复。能否实现元素的排序和避免重复?
比较器看起来像:
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;
};
你误解了一些事情。 TreeSet确实消除了重复,'a duplicate'定义为'any two elements for which your compare method returns 0'。树集中不能同时存在 2 个这样的元素。如果你这么说,我确定你的代码不起作用,但你粘贴的代码不是问题,TreeSet 的代码也不是。
一个简单的例子:
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]
注意 'World' 是如何消失的,因为比较器说它等于 Hello(它们都是 5 长度,a.length() - b.length() 返回 0,并且根据树集,0 是 'equal, thus, eliminate the duplicate')。换句话说,您粘贴的代码 会 消除重复项,问题出在其他地方。
这段代码和你的几乎一样。
比较器链接
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;
}
}