Comparable和Comparator接口都是为了对类进行比较,众所周知,诸如Integer,double等基本数据类型,java可以对他们进行比较,而对于类的比较,需要人工定义比较用到的字段比较逻辑。可以把Comparable理解为内部比较器,而Comparator是外部比较器,基本的写法如下:

class Apple implements Comparable<Apple>{

int id;

double price;

public Apple(int id, double price) {

this.id = id;

this.price = price;

}

public int compareTo(Apple o) {

//return Double.compare(this.getPrice(),o.getPrice());

if (Math.abs(this.price-o.price)<0.001)

return 0;

else

return (o.price-this.price)>0?1:-1;

}

@Override

public String toString() {

return "Apple{" +

"id=" + id +

", price=" + price +

'}';

}

}

class AESComparator implements Comparator<Apple>{

public int compare(Apple o1, Apple o2) {

if (Math.abs(o1.price-o2.price)<0.001)

return 0;

else{

return (o1.price-o2.price)>0?1:-1;

}

}

}

 实现了Comparable接口的类需要实现compareTo()方法,传入一个外部参数进行比对,实现了Comparator接口的方法需要实现compare()方法,对外部传入的两个类进行比较,从而让外部方法在比较时调用。

 两者的区别是实现Comparator接口代码更加灵活,可以定义某个类的多个比较器,从而在排序时根据实际场景自由调用,而Comparable接口实现后便不能改动。

总结:

comparator接口:真正要实现的只有compare()方法,需要单独准备出一个类来实现comparator接口,这个类将作为指定类的排序类

public int compare(Emp o1,Emp,o2){

return o1.id - o2.id

}

这是说如果o1的id - o2的id是正数就升序,如果负数降序。如果0就剔除

>=1  升序

<=-1 降序

=0 重复,不记录

comparable接口

实现该类接口不需要重新创建一个排序的类,使用接口compareble接口排序,只要重写里面的compareTo()方法

Collections类是一个包装类,它包含有各种有关集合操作的静态方法。就像一个工具类。

Collections.sort()

sort()排序方法,根据元素的自然排序对指定列表按升序进行排序

public static <T>void sort(List<T> list,Comparator<>),根据指定比较器产生的顺序对指定列表进行排序,此列表内的所有元素都必须可使用指定的比较器相互比较

参数:list——要排序的列表

C——确定列表顺序的比较器

在Java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题。

通常对象之间的比较可以从两个方面去看:

第一个方面:对象的地址是否一样,也就是是否引用自同一个对象。这种方式可以直接使用“==“来完成。

第二个方面:以对象的某一个属性的角度去比较。

从最新的JDK8而言,有三种实现对象比较的方法:

一、覆写Object类的equals()方法;

二、继承Comparable接口,并实现compareTo()方法;

三、定义一个单独的对象比较器,继承自Comparator接口,实现compare()方法。

由于使用的排序方式的不同,具体选择哪种方法来实现对象的比较也会有所不同。

覆写equals()方法,一般用于自己实现对象数组排序的情况,而对于要使用java内置的排序算法时,使用后面两种方式都是可行的。

先来看第二种方式,这种方式就是让自己编写的类继承Comparable接口,并实现compareTo()方法,这种情况下,在使用java.util.Arrays.sort()

方法时,不用指定具体的比较器,sort()方法会使用对象自己的比较函数来完成对象的排序。下面是一个具体的例子:

[java] view plain copy

import java.util.Arrays;

class BookCook implements Comparable<BookCook>{

private String title;

private double price;

public BookCook(String title,double price){

this.title = title;

this.price = price;

}

@Override

public String toString() {

return "书名:"+this.title+",价格:"+this.price;

}

@Override

public int compareTo(BookCook o) {

if(this.price > o.price){

return 1;

}else if(this.price < o.price){

return -1;

}else{

return 0;

}

}

}

一般我们使用以上两种方法就能够满足实际的开发问题。但是当出现以下情况时,就需要用到Comparator接口:

要在已经开发好的代码的基础上完善对象的比较功能时,又不想更改之前的代码,这种情况下,从JDK1.8之后出现了Comparator接口,是对这种情况的一个弥补。

这种情况下,我们需要单独定义一个对象比较器,继承Comparator接口,并实现compare()方法。示例代码如下:

[java] view plain copy

class Student {

private String name;

private double score;

public Student(String name,double score){

this.name = name;

this.score = score;

}

public double getScore(){

return this.score;

}

@Override

public String toString() {

return "姓名:"+this.name+",分数:"+this.score;

}

}

class StudentComparator implements Comparator<Student> {

@Override

public int compare(Student o1,Student o2) {

if(o1.getScore() > o2.getScore()){

return 1;

}else if(o1.getScore() < o2.getScore()){

return -1;

}else{

return 0;

}

}

}

public class TestComparator {

public static void main(String[] args) {

Student[] sts = new Student[]{

new Student("小戴",60),

new Student("小王",90),

new Student("老王",80),

new Student("小萱",95)

};

java.util.Arrays.sort(sts, new StudentComparator());

System.out.println(java.util.Arrays.toString(sts));

}

}

Java中存在比较运算符:> 、< 、>=、<=、!=、==、instanceof

只能比较基本数据类型,如果对于对象无法进行比较,如果在对象中需要实现对象之间的比较,只能通过Comparable、Compartor接口实现

(1) Comparable接口(自然排序)

String、包装类都已经默认实现了mt4下载教程Comparable接口,并重写了int compareTo(T o)方法(定义排序规则),所以String、包装类都是可以进行排序的

默认是按照升序进行排序的

int compareTo(T o)

如果返回值是正数,代表调用者(this)的值比o的值要大

如果返回值是负数,代表调用者(this)的值比o的值要小

如果返回值是0,代表调用者(this)的值比o的值相等

如果一个自定义类需要实现排序功能,需要让当前类实现Comparable接口,重写int compareTo(T o)方法,在该方法中重写排序的规则

如果一个类一旦实现了Comparable接口,那么这个类的对象在任意地方都可以进行排序或者比较

/*

String、包装类都已经默认实现了Comparable接口,并重写了int compareTo(T o)方法

*/

public class CompareDemo {

public static void main(String[] args) {

int[] arr = {5,4,2,1,3};

Arrays.sort(arr);

System.out.println(Arrays.toString(arr));

String[] s = {"AA","CC","ZZ","BB","JJ"};

Arrays.sort(s);

System.out.println(Arrays.toString(s));

}

}

/*

对象之间比较

*/

public class CompareDemo {

public static void main(String[] args) {

Employee[] e = new Employee[5];

e[0] = new Employee("e001","Jack","d001");

e[1] = new Employee("e005","Tom","d010");

e[2] = new Employee("e010","Jack","d011");

e[3] = new Employee("e004","Rose","d005");

e[4] = new Employee("e009","Marry","d008");

Arrays.sort(e);

System.out.println(Arrays.toString(e));

}

}

class Employee implements Comparable<Employee>{

private String eno;

private String ename;

private String dept;

public String getEno() {

return eno;

}

public void setEno(String eno) {

this.eno = eno;

}

public String getEname() {

return ename;

}

public void setEname(String ename) {

this.ename = ename;

}

public String getDept() {

return dept;

}

public void setDept(String dept) {

this.dept = dept;

}

public Employee(String eno, String ename, String dept) {

super();

this.eno = eno;

this.ename = ename;

this.dept = dept;

}

public Employee() {

super();

}

@Override

public String toString() {

return "Employee [eno=" + eno + ", ename=" + ename + ", dept=" + dept + "]";

}

@Override

public int compareTo(Employee o) {

//借助String的compareTo方法

return this.eno.compareTo(o.eno);

}

}

(2)Comparator接口(定制排序)

如果一个类没有实现Comparable接口,但是这个类又不方便实现Comparable接口(开闭原则),或者一个类已经实现了Comparable接口,但是其中的compareTo不满足我们的需求,那么我们可以使用Comparator接口方式进行定制排序

默认升序

int compare(T o1,T o2)

o1>o2 返回正数

o1<o2 返回负数

o1==o2 返回0

public class CompareDemo {

public static void main(String[] args) {

Employee[] e = new Employee[5];

e[0] = new Employee("e001","Jack","d001");

e[1] = new Employee("e003","Tom","d010");

e[2] = new Employee("e003","Jack","d011");

e[3] = new Employee("e004","Rose","d005");

e[4] = new Employee("e002","Marry","d008");

Arrays.sort(e, new Comparator<Employee>() {

@Override

public int compare(Employee o1, Employee o2) {

if(o1.getEno().compareTo(o2.getEno())!=0) {

return o1.getEno().compareTo(o2.getEno());

}else {

return -o1.getEname().compareTo(o2.getEname());

}

}

});

System.out.println(Arrays.toString(e));

}

}

class Employee {

private String eno;

private String ename;

private String dept;

public String getEno() {

return eno;

}

public void setEno(String eno) {

this.eno = eno;

}

public String getEname() {

return ename;

}

public void setEname(String ename) {

this.ename = ename;

}

public String getDept() {

return dept;

}

public void setDept(String dept) {

this.dept = dept;

}

public Employee(String eno, String ename, String dept) {

super();

this.eno = eno;

this.ename = ename;

this.dept = dept;

}

public Employee() {

super();

}

@Override

public String toString() {

return "Employee [eno=" + eno + ", ename=" + ename + ", dept=" + dept + "]";

}

}

最新文章

  1. 微信分享ios设备没有分享图标安卓有分享图标 (分享功能没有问题)
  2. WPS for Linux(ubuntu)字体配置(字体缺失解决办法)
  3. text .global_start 和_start
  4. 每天2分钟平板支撑Plank,锻炼核心肌群,远离背疼痛
  5. tomcat服务器配置及使用
  6. shareplex的安装&amp;&amp;起停服务(添加新用户)
  7. CI框架篇之模型篇--AR操作(2)
  8. [JIT_APP]Java基础知识总结
  9. javascript实现倒计时程序
  10. 无法启动此程序,因为计算机中丢失QtCore4.dll。尝试重新安装该程序以解决此问题(在系统里添加3个路径)
  11. Qt学习经验之quit()、exit()、close()《转载》
  12. string转QBytearray
  13. DAY23、面向对象特性
  14. selenium——find_element_by_xx 与 find_element(By.XX,&#39;XXXX&#39;)
  15. Express实例代码分析1——简单的用户验证登录文件
  16. Android6.0机型上调用系统相机拍照返回的resultCode值始终等于0的问题
  17. Linux下配置ssh免密远程登录
  18. bat文件去括号
  19. Android网络框架之Retrofit + RxJava + OkHttp 变化的时代
  20. MySql 定时完成备份

热门文章

  1. Fiddler手机抓包配置
  2. iptables 防火墙(上)
  3. Translucent System Bar 的最佳实践
  4. CSS文字超出省略
  5. spring在注解标注的方法上加切面
  6. shell脚本每五分钟执行一次可执行程序(nohup)
  7. 【Nacos】本地集群部署
  8. react 教程—核心概念
  9. Ext 选项卡面板TabPanel
  10. Golang flag包使用详解(一)