我的理解是Comparator可以比较来自不同类的多个对象,而Comparable只能将一个onject与同一个类中的另一个实例进行比较。
比较(object1) 比较(object1,object2)
以上解释是否属实?
答案 0 :(得分:7)
不是真的。
Comparable
和Comparator
是通用接口,允许比较泛型(包括的子类)中定义的类型的实例。
它们之间的主要区别在于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等。