TreeSet构造函数与Comparator <! - ? - >参数

时间:2015-04-17 12:22:40

标签: java generics comparator treeset

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

TreeSet(Comparator<? super E> c)

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

10 个答案:

答案 0 :(得分:14)

TreeSet中的元素保持排序。

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

如果您想要不同的排序,请在构造函数中提供Comparator。

答案 1 :(得分:7)

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

由于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 "]

答案 2 :(得分:5)

此构造函数允许您定义将Comparator插入T后面的树时使用的Set

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

答案 3 :(得分:1)

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

请参阅javadoc

  

公共TreeSet(比较器比较器)

     

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

     

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

     

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

     

<强>参数:

     

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

有关自然物体排序的更多信息,请参阅here

答案 4 :(得分:1)

TreeSetbinary search tree,它基于给出两个元素 a b 的概念,它就是这种情况 a 小于&#34;小于&#34; b ,或不。但是,如果您定义自己的类,TreeSet不知道如何确定该类的给定对象是否小于&#34;另一个目标,因为它无法知道你对物体的预期解释。内容。因此,您可以创建Comparator代表TreeSet进行比较。

答案 5 :(得分:1)

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 :(得分:1)

Treeset类具有以下构造函数,以便Treeset使用比较器c所描述的顺序存储元素.Below是一个示例来说明相同的内容。

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

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

希望这能回答这个问题。

答案 7 :(得分:1)

您还可以在Java8中使用Lambda

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

答案 8 :(得分:0)

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

它提供了多个排序顺序,即您可以根据任何数据成员对元素进行排序。例如,它可能在rollno,名称,年龄或其他任何东西。

通过在TreeSet(Comparator<? super E> c)中传递比较器,这意味着您可以根据所需的参数订购TreeSet。

  

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

假设您有TreeSet<User>并且您的用户类中包含字段id

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

答案 9 :(得分:0)

使用默认构造函数的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";
}
}

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