何时使用Comparable和Comparator

pkr*_*ish 106 java comparable comparator

我有一个对象列表,我需要在一个字段上排序,比如分数.在没有多想的情况下,我编写了一个实现Comparator的新类,它可以执行任务并且可以正常运行.

现在回过头来看,我想知道我是否应该让我的类实现Comparable,而不是创建一个实现Comparator的新类.分数是对象将被订购的唯一字段.

  1. 我做过什么可以接受的做法?

  2. 是正确的方法"首先让类实现Comparable(对于自然顺序),如果需要替代字段比较,那么创建一个实现Comparator的新类"?

  3. 如果上面的(2)为真,那么它是否意味着只有在具有类实现Comparable之后才应该实现Comparator?(假设我拥有原始课程).

Bal*_*usC 124

使用Comparable,如果要定义一个默认的(天然)排序问题的对象的行为,常见的做法是使用的技术或自然(数据库?)的对象标识符这一点.

使用Comparator如果要定义一个外部可控有序的行为,这可以覆盖默认排序行为.

  • 它告诉_when_使用每一个 - 如果这不是最佳实践,它是什么? (39认同)
  • 这是一个技术性的解释,并且它们来得正确,但它并没有真正说明最佳实践. (3认同)
  • “实施‘Comparable’是否意味着我正在定义自然顺序?” ,这给了我我正在寻找的答案。谢谢 :) (3认同)

Yis*_*hai 78

我会说一个对象应该实现Comparable,如果这是对类进行排序的明确自然方式,并且任何人都需要对类进行排序通常会想要这样做.

但是,如果排序是类的异常使用,或者排序仅对特定用例有意义,那么比较器是更好的选择.

换句话说,给定类名,是否可以比较排序,或者你是否必须求助于阅读javadoc?如果是后者,赔率是未来每一分拣用例将需要一个比较,在这点可比的实现可能的类的用户放慢,而不是加速它们.

  • 你可以参考http://java-journal.blogspot.in/2011/01/when-to-use-comparable-and-when-to-use.html (2认同)

Boz*_*zho 57

用途Comparable:

  • 如果对象在您的控制之下.
  • 如果比较行为是主要的比较行为.

用途Comparator:

  • 如果对象超出您的控制范围,您无法实现它们Comparable.
  • 当您想要比较不同于默认(由指定的Comparable)行为的行为时.


Yas*_*ash 20

可比 -java.lang.Comparable: int compareTo(Object o1)

可比较的对象能够将自己与另一个对象进行比较.类本身必须实现java.lang.Comparable接口才能比较其实例.

  • 能够将当前对象与提供的对象进行比较.
  • 通过使用它,我们可以only one sort sequence基于实例属性实现.EX:Person.id
  • 一些预定义类(如String,Wrapper类,Date,Calendar)已实现Comparable接口.

比较者 -java.util.Comparator: int compare(Object o1, Object o2)

比较器对象能够比较两个不同的对象.该类不是比较它的实例,而是比较其他类的实例.此比较器类必须实现java.util.Comparator接口.

  • 能够比较任何两个相同类型的对象.
  • 通过使用它,我们可以many sort sequence根据实例属性实现和命名每个.EX:Person.id, Person.name, Person.age
  • 我们可以为我们的预定义类实现Comparator接口以进行自定义排序.

例:

public class Employee implements Comparable<Employee> {

    private int id;
    private String name;
    private int age;
    private long salary;

    // Many sort sequences can be created with different names.
    public static Comparator<Employee> NameComparator = new Comparator<Employee>() {         
        @Override
        public int compare(Employee e1, Employee e2) {
            return e1.getName().compareTo(e2.getName());
        }
    };
    public static Comparator<Employee> idComparator = new Comparator<Employee>() {       
        @Override
        public int compare(Employee e1, Employee e2) {
            return Integer.valueOf(e1.getId()).compareTo(Integer.valueOf(e2.getId()));
        }
    };

    public Employee() { }
    public Employee(int id, String name, int age, long salary){
        this.id = id;
        this.name = name;
        this.age = age;
        this.salary = salary;
    }
    // setters and getters.

    // Only one sort sequence can be created with in the class.
    @Override
    public int compareTo(Employee e) {
    //return Integer.valueOf(this.id).compareTo(Integer.valueOf(e.id));
    //return Character.toString(this.name.charAt(0)).compareToIgnoreCase(Character.toString(e.name.charAt(0)));
        if (this.id > e.id) {
            return 1;
        }else if(this.id < e.id){
            return -1;
        }else {
            return Character.toString(this.name.charAt(0)).compareToIgnoreCase(Character.toString(e.name.charAt(0)));
        }

    }   

    public static void main(String[] args) {

        Employee e1 = new Employee(5, "Yash", 22, 1000);
        Employee e2 = new Employee(8, "Tharun", 24, 25000);

        List<Employee> list = new ArrayList<Employee>();
        list.add(e1);
        list.add(e2);
        Collections.sort(list); // call @compareTo(o1)
        Collections.sort(list, Employee.nameComparator); // call @compare (o1,o2)
        Collections.sort(list, Employee.idComparator); // call @compare (o1,o2)
    }
}
Run Code Online (Sandbox Code Playgroud)
  • 对于自定义排序,我们选择比较器@compare(o1,o2)用于我们用于比较@compareTo(o1)的其他场景,如果我们想要对多个场进行排序,那么我们使用比较器.

对于Java 8 Lambda:Comparator参考我的帖子.


小智 10

比较同一类的实例时应使用Comparable.

比较器可用于比较不同类的实例.

Comparable由类实现,需要为其对象定义自然顺序.像String实现Comparable.

如果一个人想要一个不同的排序顺序,那么他可以实现比较器并定义自己比较两个实例的方式.


小智 9

比较器做了可比较的一切,再加上更多.

| | Comparable | Comparator ._______________________________________________________________________________ Is used to allow Collections.sort to work | yes | yes Can compare multiple fields | yes | yes Lives inside the class you’re comparing and serves | | as a “default” way to compare | yes | yes Can live outside the class you’re comparing | no | yes Can have multiple instances with different method names | no | yes Input arguments can be a list of | just Object| Any type Can use enums | no | yes

我发现使用比较器作为匿名类的最佳方法如下:

private static void sortAccountsByPriority(List<AccountRecord> accounts) {
    Collections.sort(accounts, new Comparator<AccountRecord>() {

        @Override
        public int compare(AccountRecord a1, AccountRecord a2) {
            return a1.getRank().compareTo(a2.getRank());
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

您可以在计划排序的类中创建此类方法的多个版本.所以你可以:

  • sortAccountsByPriority
  • sortAccountsByType
  • sortAccountsByPriorityAndType

    等等...

现在,您可以在任何地方使用这些排序方法并获得代码重用.这给了我一切可比的东西,加上更多...所以我认为没有任何理由可以使用比较.


ext*_*eon 8

我会说:

  • 如果比较直观,那么一定要实现Comparable
  • 如果不清楚您的比较是否直观,请使用比较器,因为它更明确,因此对于必须维护代码的穷人来说更清楚
  • 如果有多个直观比较可能,我更喜欢比较器,可能是通过类中的工厂方法构建来进行比较.
  • 如果比较是特殊目的,请使用Comparator


a L*_*ner 7

以下几点可以帮助您决定在哪些情况下应该使用 Comparable 以及在哪种 Comparator 中使用:

1) 代码可用性

2) 单与多排序标准

3) Arays.sort() 和 Collection.sort()

4) 作为 SortedMap 和 SortedSet 中的键

5)更多的类与灵活性

6) 类间比较

7) 自然秩序

有关更详细的文章,您可以参考何时使用可比较以及何时使用比较器


Job*_*ews 6

如果对象的排序需要基于自然顺序,则请使用Comparable,而如果需要对不同对象的属性进行排序,请使用Java中的Comparator。

可比和比较器之间的主要区别:

+------------------------------------------------------------------------------------+
¦               Comparable                ¦                Comparator                ¦
¦-----------------------------------------+------------------------------------------¦
¦ java.lang.Comparable                    ¦ java.util.Comparator                     ¦
¦-----------------------------------------+------------------------------------------¦
¦ int objOne.compareTo(objTwo)            ¦ int compareTo(objOne, objTwo)            ¦
¦-----------------------------------------+------------------------------------------¦
¦ Negative, if objOne < objTwo            ¦ Same as Comparable                       ¦
¦ Zero,  if objOne == objTwo              ¦                                          ¦
¦ Positive,  if objOne > objTwo           ¦                                          ¦
¦-----------------------------------------+------------------------------------------¦
¦ You must modify the clas whose          ¦ You build a class separate from to sort. ¦
¦ instances you want to sort.             ¦ the class whose instances you want       ¦
¦-----------------------------------------+------------------------------------------¦
¦ Only one sort sequemce can be created   ¦ Many sort sequences can be created       ¦
¦-----------------------------------------+------------------------------------------¦
¦ Implemented frequently in the API by:   ¦ Meant to be implemented to sort          ¦
¦ String, Wrapper classes, Date, Calandar ¦ instances of third-party classes.        ¦
+------------------------------------------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)


小智 5

如果您需要自然顺序排序 - 用户可比较 如果您需要自定义顺序排序 - 使用比较器

例子:

Class Employee{
private int id;
private String name;
private String department;
}
Run Code Online (Sandbox Code Playgroud)

自然顺序排序将基于 ID,因为它是唯一的,而自定义顺序排序将是名称和部门。

参考资料:
一个类什么时候应该是可比较的和/或比较器的? http://javarevisited.blogspot.com/2011/06/comparator-and-comparable-in-java.html