I wan to create TreeSet()
that will sort my elements with my predefined comparator. 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. 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'. No 2 such elements can both exist in a treeset. 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.
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). In other words, your code as pasted would eliminate duplicates, the problem lies elsewhere.
This code is almost the same as yours.
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;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.