Java 带有 Comparator<?> 参数的 TreeSet 构造函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29699103/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 08:28:16  来源:igfitidea点击:

TreeSet constructor with Comparator<?> parameter

javagenericscomparatortreeset

提问by TheRapture87

In Java's documentation for its class TreeSet one of the constructors is shown to have the following header:

在其类 TreeSet 的 Java 文档中,构造函数之一显示为具有以下标题:

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.

有人可以帮助解释为什么 TreeSet 有一个以比较器对象作为参数的构造函数吗?我不知道为什么要这样做。

采纳答案by Eran

The elements in a TreeSet are kept sorted.

TreeSet 中的元素保持排序。

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.

如果您使用没有 Comparator 的构造函数,元素类(由 的实现定义Comparable)的自然顺序将用于对 TreeSet 的元素进行排序。

If you want a different ordering, you supply a Comparator in the constructor.

如果您想要不同的顺序,您可以在构造函数中提供一个 Comparator。

回答by Umberto Raimondi

It's used to sort the elements of the Set according to user-defined rules.

它用于根据用户定义的规则对 Set 的元素进行排序。

See the javadoc:

请参阅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.

公共树集(比较器比较器)

构造一个新的空树集,根据指定的比较器排序

插入到集合中的所有元素必须通过指定的比较器相互比较:comparator.compare(e1, e2) 不能为集合中的任何元素 e1 和 e2 抛出 ClassCastException。

如果用户尝试向集合中添加违反此约束的元素,则 add 调用将抛出 ClassCastException。

参数:

比较器- 将用于订购此集合的比较器。如果为 null,则将使用元素的自然顺序。

See herefor more information on natural objects ordering.

有关自然物体排序的更多信息,请参见此处

回答by Abhishek

Comparator interface is used to order the objects of user-defined class.

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.

它提供多种排序顺序,即您可以根据任何数据成员对元素进行排序。例如,它可能在 rollno、姓名、年龄或其他任何内容上。

By passing a Comparator in TreeSet(Comparator<? super E> c)it means that you can order your TreeSet based on the parameter you desire.

通过在其中传递 ComparatorTreeSet(Comparator<? super E> c)意味着您可以根据所需的参数对 TreeSet 进行排序。

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.

我们可以说,通过在 TreeSet 中传递一个 Comparator,我们可以根据需要对 TreeSet 进行排序,而不是使用 TreeSet 使用的自然排序。

Suppose you have TreeSet<User>and you have a User class with field idin it.

假设您有TreeSet<User>并且您有一个带有字段的 User 类id

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.

现在,如果您想根据用户 ID 对 TreeSet 进行排序,您可以在 TreeSet 中传递一个 Comparator 对象以获得所需的排序。

回答by Abhishek

This constructor allows you define the Comparatorthat is used when inserting a Tinto the tree that is behind the Set.

此构造函数允许您定义Comparator在将 a 插入TSet.

Comparator<String> comp = (String o1, String o2) -> (o1.compareTo(o2));
Set<String> ts = new TreeSet<>(comp);

回答by Aasmund Eldhuset

A TreeSetis a binary search tree, which is based on the notion that given two elements aand b, it is either the case that ais "smaller than" b, or not. However, if you define your own class, the TreeSetdoesn'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 Comparatorwhich can do the comparisons on behalf of the TreeSet.

ATreeSet是一个二叉搜索树,它基于给定两个元素ab的概念,要么a“小于” b,要么不。但是,如果您定义自己的类,则TreeSet它不知道如何确定该类的给定对象是否“小于”另一个对象,因为它无法知道您对对象内容的预期解释。因此,您可以创建一个Comparator可以代表TreeSet.

回答by venkatesh.khandare

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();
  }
}

回答by iftekhar khan

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.

Treeset 类具有以下构造函数,以便 Treeset 按照 Comparator c 描述的顺序使用 存储元素。下面是一个示例来说明相同的内容。

    **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. Output2 1 3

在这里,如果您看到 namecomp 正在实现 Comparator 接口,从而根据 Name 字段按降序对 Employeee 类的元素进行排序。现在 Treeset 正在实现 namecomp 比较器以根据 Name 字段按降序存储元素。 输出2 1 3

Hope this answers the question.

希望这能回答这个问题。

回答by Vivek Kumar

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.

带有默认构造函数的 TreeSet 将按自然升序对元素进行排序,但是如果您想要根据您的要求进行一些自定义排序,那么您应该使用 Comparator 接口。eq 这是您的默认类 Employee,然后您想根据薪水对此类进行排序。

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.

这里我们通过实现 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);
}
}

回答by Giovanni P.

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.

以上所有答案都是正确的,但我想补充一点,除了导致不同的排序之外,自定义 Comparator 还会以不同的方式过滤值。

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 的值是单义的,如果自定义 Comparator 返回两个值相同的值,则只有其中一个会出现在 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 "]

回答by lennon310

You can also use Lambda with Java8

您还可以将 Lambda 与 Java8 结合使用

Set<T> s = new TreeSet<>((a, b) -> func(a) - func(b));