问题
In Java’s documentation for its class TreeSet one of the constructors is shown to have the following header:
TreeSet(Comparator<? super E> c)
Can someone help explain why there is a constructor for TreeSet which takes a comparator object as its argument? I have no clue why this is done.
回答1:
The elements in a TreeSet are kept sorted.
If you use a constructor that has no Comparator, the natural ordering of the element class (defined by the implementation of Comparable
) would be used to sort the elements of the TreeSet.
If you want a different ordering, you supply a Comparator in the constructor.
回答2:
All the above answers are correct, but I would like to add that a custom Comparator, apart from resulting in a different sorting, will also filter values differently.
Since Set's values are univocal, if the custom Comparator returns that two values are identical only one of them will appear in the Set:
Set<String> s = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.trim().compareTo(s2.trim());
}
});
s.add("1");
s.add(" 1");
s.add("2 ");
s.add("2");
s.add(" 2 ");
Arrays.toString(s.toArray()); // [ "1", "2 "]
回答3:
This constructor allows you define the Comparator
that is used when inserting a T
into the tree that is behind the Set
.
Comparator<String> comp = (String o1, String o2) -> (o1.compareTo(o2));
Set<String> ts = new TreeSet<>(comp);
回答4:
A TreeSet
is a binary search tree, which is based on the notion that given two elements a and b, it is either the case that a is "smaller than" b, or not. However, if you define your own class, the TreeSet
doesn't know how to determine whether a given object of that class is "smaller than" another object because it can't know your intended interpretation of the objects' contents. Therefore, you can create a Comparator
which can do the comparisons on behalf of the TreeSet
.
回答5:
The following code shows how to use TreeSet.TreeSet(Comparator <? super E > comparator) constructor.
/**
*Output:
F E D C B A
*/
import java.util.Comparator;
import java.util.TreeSet;
class MyComparator implements Comparator<String> {
public int compare(String a, String b) {
String aStr, bStr;
aStr = a;
bStr = b;
return bStr.compareTo(aStr);
}
// No need to override equals.
}
public class MainClass {
public static void main(String args[]) {
TreeSet<String> ts = new TreeSet<String>(new MyComparator());
ts.add("C");
ts.add("A");
ts.add("B");
ts.add("E");
ts.add("F");
ts.add("D");
for (String element : ts)
System.out.print(element + " ");
System.out.println();
}
}
回答6:
It's used to sort the elements of the Set according to user-defined rules.
See the javadoc:
public TreeSet(Comparator comparator)
Constructs a new, empty tree set, sorted according to the specified comparator.
All elements inserted into the set must be mutually comparable by the specified comparator: comparator.compare(e1, e2) must not throw a ClassCastException for any elements e1 and e2 in the set.
If the user attempts to add an element to the set that violates this constraint, the add call will throw a ClassCastException.
Parameters:
comparator - the comparator that will be used to order this set. If null, the natural ordering of the elements will be used.
See here for more information on natural objects ordering.
回答7:
Treeset class has the below constructor so that Treeset stores the element using the in the order as described by the Comparator c.Below is an example to illustrate the same.
**Constructor :-**
TreeSet(Comparator<? super E> c)
class Employeee {
public Employeee(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private int id;
private String name;
}
class namecomp implements Comparator<Employeee> {
public int compare(Employeee paramT1, Employeee paramT2) {
if (paramT1.getName().compareTo(paramT2.getName()) > 0)
return -1;
else if (paramT1.getName().compareTo(paramT2.getName()) < 0)
return 1;
else
return 0;
}
}
public class TreeSetImpl {
public static void main(String[] args) {
SortedSet<Employeee> treeSet = new TreeSet<Employeee>(new namecomp());
Employeee e1 = new Employeee(1, "Iftekhar");
Employeee e2 = new Employeee(2, "Khan");
Employeee e3 = new Employeee(3, "Apple");
treeSet.add(e1);
treeSet.add(e2);
treeSet.add(e3);
Iterator<Employeee> it = treeSet.iterator();
while (it.hasNext()) {
System.out.println(it.next().getId());
}
}
}
Here if you see the namecomp is implementing the Comparator interface and thus sorting the elements of the Employeee class in the descending order on the basis of the Name field. Now the Treeset is implementing the namecomp comparator to store the element in the descending order on the basis of the Name field. Output 2 1 3
Hope this answers the question.
回答8:
Comparator interface is used to order the objects of user-defined class.
It provides multiple sorting sequence i.e. you can sort the elements based on any data member. For instance it may be on rollno, name, age or anything else.
By passing a Comparator in TreeSet(Comparator<? super E> c)
it means that you can order your TreeSet based on the parameter you desire.
We can say that by passing a Comparator in TreeSet we can order the TreeSet as we desire and not use the natural ordering used by TreeSet.
Suppose you have TreeSet<User>
and you have a User class with field id
in it.
Now if you want to sort your TreeSet based on User id you can pass a Comparator object in your TreeSet to obtain the desired ordering.
回答9:
TreeSet with default constructor will sort the element in natural ascending order, but if you want some custom sorting according to your requirement then you should go for the Comparator interface. eq This is your default class Employee and you want to sort this class according to salary then.
public class Employee {
private int Id;
private String name;
private int salary;
public Employee(int id, String name, int salary) {
super();
Id = id;
this.name = name;
this.salary = salary;
}
public int getId() {
return Id;
}
public void setId(int id) {
Id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public String toString() {
return "ID : "+Id +" Name : "+name+" Salary : "+salary+"\n";
}
}
Here we have created another class by implementing Comparator.
public class EmpSalaryComparator implements Comparator{
public int compare(Object o1, Object o2) {
Employee e1=(Employee) o1;
Employee e2=(Employee) o2;
return e1.getSalary()-e2.getSalary();
}
}
public class Test1 {
public static void main(String[] args) {
TreeSet t1=new TreeSet(new EmpSalaryComparator());
Employee e1=new Employee(1001, "Ram", 1000);
Employee e2=new Employee(1002, "lucky", 7000);
Employee e3=new Employee(1003, "sumo", 3000);
Employee e4=new Employee(1004, "kharvi", 3000);
Employee e5=new Employee(1005, "priya", 1000);
t1.add(e1);
t1.add(e2);
t1.add(e3);
t1.add(e4);
t1.add(e5);
System.out.println(t1);
}
}
来源:https://stackoverflow.com/questions/29699103/treeset-constructor-with-comparator-parameter