• 欢迎访问天天编码网站,Java技术、技术书单、开发工具,欢迎加入天天编码
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏天天编码吧
  • 我们的淘宝店铺已经开张了哦,传送门:https://shop145764801.taobao.com/

深入解析Java的Comparable与Comparator

Java基础 tiantian 2891次浏览 0个评论 扫描二维码

Java的核心API提供了两个名称类似、功能暧昧的接口:ComparableComparator 。从它们的名字可以看出,它们肯定都是与比较功能有关的接口。问题是:它们都是具有什么功能呢?又该如何使用呢?这两个接口之间有什么联系和区别呢?本文将通过两个示例代码来回答这些问题,这两个实例代码都是要比较两个Cat对象的大小,我们通过代码演示如何分别使用Comparable与Comparator来完成功能。

深入解析Java的Comparable与Comparator

Comparable

当一个类希望使得自己的对象可以直接与其他的对象比较时,该类就应该去 implements(实现) Comparable接口。该类本身需要实现这个接口,这样该类的对象之间就可以相互比较了。Comparable接口中只有一个 compareTo() 方法,实现Comparable接口就意味着要实现该方法,该方法也就是实现定制化比较策略的地方。我们直接看一个代码片段:

class Cat implements Comparable<Cat> {
private int size;
private String brand;

public Cat(int size, String brand) {
this.size = size;
this.brand = brand;
}

@Override
public int compareTo(Cat cat) {
if (this.size > cat.size) return 1;
else if (this.size < cat.size) return -1;
else return 0;
}
}

public class Main {
public static void main(String[] args) {
Cat catA = new Cat(12, “天天编码”);
Cat catB = new Cat(10, “天天睡觉”);
if (catA.compareTo(catB) > 0) {
System.out.println(catA.brand + ” is better.”);
} else {
System.out.println(catB.brand + ” is better.”);
}
}
}

建议仔细思考得出答案后,上机验证答案。正确的答案是:

天天编码 is better.

Comparator

通过实现Comparable接口,可以让某类具有可比较性。但是,在某些情况下,你可能不想或者不能去修改类的源代码。同时,你又希望可以基于对象的某些属性或字段去比较对象的大小,此时,我们就可以让该某类实现Comparator接口。举例来说,你可能需要使用高度或者年龄来比较两个人的大小。

Comparator接口同样只含有一个 compare() 方法,所以,实现Comparator接口的类也只需要实现一个compare()方法。现在,让我们尝试使用另一种方法来比较两只猫的大小。Comparator接口的最常见使用场景是实现排序功能。JDK中的 CollectionsArrays 提供的便利排序方法都是使用了Comparator接口。示例代码如下:

class Cat {
private int size;
private String brand;

public Cat(int size, String brand) {
this.size = size;
this.brand = brand;
}
}

class SizeComparator implements Comparator<Cat> {
@Override
public int compare(Cat catA, Cat catB) {
if (catA.size > catB.size) return 1;
else if (catA.size < catB.size) return -1;
else return 0;
}
}

public class Main {
public static void main(String[] args) {
Cat catA = new Cat(12, “天天编码”);
Cat catB = new Cat(14, “天天进步”);
Cat catC = new Cat(10, “好好学习”);

ArrayList<Cat> cats = new ArrayList<>();
cats.add(catA);
cats.add(catB);
cats.add(catC);

Collections.sort(cats, new SizeComparator());
for (Cat cat : cats) {
System.out.println(cat.brand);
}
}
}

建议仔细思考得出答案后,上机验证答案,正确的答案是:

好好学习
天天编码
天天进步

通过使用定制化的SizeComparator,我们改变了ArrayList集合对于Cat元素排序的逻辑。

总结

简单而言,一个实现了Comparable接口的类是具有可比较性的类,意味着该类的多个对象之间可以相互比较大小。

一个实现了Comparator接口的类主要在两种情况下使用:
1. 作为策略对象传递给排序方法,精确控制排序方法的排序结果。比如 Collections.sort() 和 Arrays.sort() 。
2. 作为策略对象传递给集合容器,精确控制容器的排序算法。比如 有序Set(TreeSet) 和 有序Map(TreeMap)。

最后,我们再引入一个使用TreeSet的例子阐述一下两个的联系与区别。为了创建一个TreeSet对象,我们既可以传递一个Comparator给TreeSet构造器,也可以让TreeSet容器的元素实现Comparable接口。

代码片段一:

public class Cat {
int size;
Cat(int size) {
this.size = size;
}
}

public class SizeComparator implements Comparator<Cat> {
@Override
public int compare(Cat catA, Cat catB) {
return catA.size – catB.size;
}
}

public class ImpComparable {
public static void main(String[] args) {
TreeSet<Cat> cats = new TreeSet<Cat>(new SizeComparator());
cats.add(new Cat(1));
cats.add(new Cat(2));
cats.add(new Cat(0));
}
}

另一种实现方式:

public class Cat implements Comparable<Cat> {
int size;
Cat(int size) {
this.size = size;
}

@Override
public int compareTo(Cat cat) {
return cat.size – this.size;
}
}

public class ImpComparable {
public static void main(String[] args) {
TreeSet<Cat> cats = new TreeSet<Cat>();
cats.add(new Cat(1));
cats.add(new Cat(2));
cats.add(new Cat(0));
}
}


天天编码 , 版权所有丨本文标题:深入解析Java的Comparable与Comparator
转载请保留页面地址:http://www.tiantianbianma.com/java-comparable-comparator.html/
喜欢 (11)
支付宝[多谢打赏]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址