可比较和比较器之间的区别?

时间:2018-03-29 18:26:26

标签: java oop

我的理解是Comparator可以比较来自不同类的多个对象,而Comparable只能将一个onject与同一个类中的另一个实例进行比较。

比较(object1) 比较(object1,object2)

以上解释是否属实?

3 个答案:

答案 0 :(得分:7)

不是真的。
ComparableComparator是通用接口,允许比较泛型(包括的子类)中定义的类型的实例。

它们之间的主要区别在于Comparable直接在要比较对象的类中实现。

因此,如果您只有一种方法来比较某个类中的实例,那就是您对它们有一个自然的顺序,Comparable是正确的方法。
另一方面,如果您有多种方法来比较某个类的实例,Comparable是不够的 您应该使用Comparator代替(如果它不存在自然顺序)或使用两者(如果它存在自然顺序和其他一些顺序)。

Comparator之外Comparable可用的示例:

String类通过按字典顺序比较两个字符串来实现Comparable。 假设您需要根据不同的规则对List String进行排序:它们的长度 您需要定义实现此规则的Comparator<String>,例如:

public class StringLengthComparator implements Comparator<String> {

    @Override
    public int compare(String o1, String o2) {
        return Integer.compare(o1.length(), o2.length());
    }

}

现在您可以使用自然顺序(使用String)对Comparable进行排序:

List<String> strings = new ArrayList<>();
...
strings.sort();

但您也可以使用特定的Comparator<String>

strings.sort(new StringLengthComparator());

或者没有创建任何带有lambda的类:

strings.sort((o1,o2)->Integer.compare(o1.length(), o2.length()));

应使用Comparator代替Comparable的示例:

假设您有一个代表银行帐户的Account课程 从功能上来说,您没有自然的顺序来对它们进行排序,但您可以根据客户需求进行多个订单。 让课程实现Comparable没有意义。但是创建不同的Comparator<Account>会。

仅可使用Comparator的情况:

如果要为无法更改源代码(JDK类或第三方类)的类实例定义订单,Comparator是可以遵循的方法。

答案 1 :(得分:1)

此答案基于Intertech培训从Complete Java SE 8 Developer Bootcamp课程中提取的信息。据他们

可比较界面显示“该特定对象将 与另一个对象相比”,而比较器有点像 这个第三方“给我任何两个对象,我会告诉你 他们被订购了。”

Comparable Comparator 均位于java.util.package中。

字符串,图表,整数等均具有“自然排序”(在unicode之后,因此排序的最高优先级是数字,然后是大写字母和小写字母)。如果要对自定义类进行排序,则必须实现一个 Comparable 接口,以帮助排序方法了解它们应执行的操作(获取Collections或Arrays来对您的类型,类型进行排序)。必须实现 Comparable 接口)。

实现 Comparable 接口的类必须实现compareTo()方法。此方法采用通用对象。例如,

public class MyDate implements Comparable {
    private int day, month, year;
    public MyDate(int month, int day, int year) {
        this.day = day;
        this.year = year;
        this.month = month;
    }
    public int compareTo(Object o) {
        MyDate d = (MyDate) o;
        if (year != d.year) {
            return year - d.year;
        }
        if (month != d.month ) {
            return month - d.month;
        }
        if (day != d.day) {
            return day - d.day;
        }
        return 0;
    }
    ...
}

实现 Comparator 接口的类必须实现compare()方法。此方法以两个Object作为参数,如果第一个参数大于第二个参数,则返回一个正数;如果相等,则返回零;否则,返回一个负数。

public class MyDate implements Comparator {
    private int day, month, year;
    public MyDate(int month, int day, int year) {
        this.day = day;
        this.year = year;
        this.month = month;
    }
    public int compare(Object o1, Object o2) {
        MyDate d1 = (MyDate) o1;
        MyDate d2 = (MyDate) o2;
        if (d1.year != d2.year) {
            return d1.year - d2.year;
        }
        if (d1.month != d2.month ) {
            return d1.month - d2.month;
        }
        if (d1.day != d2.day) {
            return d1.day - d2.day;
        }
        return 0;
    }
    ...
}

比较器可用于比较任何两个对象。比较相似的对象时,最好尽可能使用 Comparable 界面。

比较器在比较异构集合的元素和我们没有来源的第三方类时很有用。

答案 2 :(得分:0)

我认为,当我们希望自然地通过多个属性比较用户定义的类时,最好使用Comparator接口,该接口允许我们创建一些实现比较器接口的类并比较每个属性。在这种情况下,我们有一个下面的代码:

<tab-content title="@lang('app.'.$question[0]->type)">
    <div id="codeEditor" class="codeEditor"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.2/ace.js"></script>
    <script>
         var aceCodeEditor = ace.edit("codeEditor");
         aceCodeEditor.setTheme("ace/theme/dracula");
         aceCodeEditor.session.setMode("ace/mode/php");
         aceCodeEditor.setValue(`abstract class Person {
             private $age = 20;
             abstract public function getAge();
         }`);
    </script>
</tab-content>

但是当我们只想使用一个属性来比较用户定义的类时,就不需要比较器了,相反,我们可以使用如下代码的可比较接口:

public class Student{
private String name;
private String ranking;
private int age;
private String country;

// getter and setter
}

public class NameComparator implements Comparator{
//compare by name attribute
}
public class AgeComparator implements Comparator{
//compare by Age attribute
}
public class CountryComparator implements Comparator{
//compare by Country attribute
}
public class RankingComparator implements Comparator{
//compare by Ranking attribute
}

如果我们从Comparator接口使用的话,这是一个不错的地方,它是用于内置实现了CompareTo方法的类的,例如number等。