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

class Apple implements Comparable{

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{

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 void sort(List 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{

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 {

@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、包装类都已经默认实现了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{

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

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() {

@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 + "]";

}

}

java 比较器类_java常用类——比较器相关推荐

  1. java常用class类_java常用类

    java常用类 内部类 1.成员内部类:在一个类的内部定义一个完整的类 例如:外部类public class Body{ 内部类class Header{ } } 内部类可以直接访问外部类的私有成员, ...

  2. Java并发包中常用类

    Java并发包中常用类小结(一) 从JDK1.5以后,Java为我们引入了一个并发包,用于解决实际开发中经常用到的并发问题,那我们今天就来简单看一下相关的一些常见类的使用情况. 1.Concurren ...

  3. Java的异常类和常用类、容器

    Java的异常类和常用类.容器 一.Java的异常类 1.异常的概念 2.异常的分类 3.try-catch语句 4.自定义异常类 二.Java的常用类 1.String类 2.StringBuffe ...

  4. java零基础Ⅱ-- 4.常用类

    java零基础Ⅱ-- 4.常用类 一.包装类 包装类的分类 包装类和基本数据的转换 演示 测试题 包装类型和String类型的相互转换 Integer类和Character类的常用方法 Integer ...

  5. Java并发包中常用类小结(一)

                                   Java并发包中常用类小结(一) 从JDK1.5以后,Java为我们引入了一个并发包,用于解决实际开发中经常用到的并发问题,那我们今天就来 ...

  6. 时间日期类JAVA包含地区属性_Java常用类 | 时间和日期类

    开发中经常涉及到时间与日期,记录下Java中与时间和日期相关的API JDK8之前与时间日期相关的类 java.lang.System类 System类提供了一个公共的静态方法currentTimes ...

  7. java 类数组_Java常用类-字符串、日期类、算法及数组工具类等

    大家好,乐字节的小乐又和大家见面了.这次要给大家讲述的是Java常用类. 主要有以下知识点: Ø 字符串相关类(String .StringBuffer.StringBuilder) Ø 算法及数组工 ...

  8. java常用类需要记吗_java 常用类

    java 常用类库 Object 类:clone(), equals(), toString() Runtime 类:代表 java 程序的运行环境 定时器: Timer 和 TimerTask 类 ...

  9. java 字符串 面试题_Java常用类String的面试题汇总(java面试题)

    1.比较两个字符串时使用"=="还是equals()方法? 当然是equals方法."=="测试的是两个对象的引用是否相同,而equals()比较的是两个字符串 ...

最新文章

  1. linux 编辑文件删除不了怎么办,Linux中文件/文件夹无法删除的解决方案
  2. MTK深圳公司嵌入式软件工程师笔试题(含部分答案)
  3. 健康管理-健康管理特点
  4. 14行代码满分:1037 在霍格沃茨找零钱 (20分)
  5. 线程控制、如何给面试官描述线程不安全的情况?模拟黄牛抢票展现不安全的情况及解决方式、互斥锁加锁解锁
  6. queue的常见用法
  7. K8s(二):130 道 K8s/Docker 配套练习题,学+练结合,一次吃透
  8. .gen地图文件的投影编程实现(以墨卡托投影和兰伯特投影为例)
  9. 已解决-安装CentOS 7时No Caching mode page found和Assuming drive cache:write through报错问题
  10. k8s kubeadm 安装
  11. angular数据绑定
  12. 命令提示符中的一些基本命令
  13. 力扣(88.53)补8.31
  14. 【EmguCV系列一】EmguCV下载安装以及配置
  15. 计算机软件工程专业心得,非计算机专业学软件工程的一点心得体会
  16. PHP7.2源码安装
  17. 自装kali进行管理员登陆
  18. matlab 绘多图 图名,MATLAB中subplot函数来画多图
  19. 对“爱吖”音乐播放器调查报告的分析
  20. Linux 管道符号

热门文章

  1. Tomcat爆出高危漏洞
  2. 程序员看《长安十二时辰》的正确姿势~!
  3. 工程师的基本功是什么?如何练习?听美团技术大咖怎么说
  4. JAVA字符串占位符替换
  5. Spring 框架基础(04):AOP切面编程概念,几种实现方式演示
  6. Python模块开发【Distutils】
  7. JavaScript 自执行函数和 jQuery扩展方法
  8. Kubernetes管理员的11条 安全军规
  9. 20180927-1
  10. 风口更需冷静 智能家居如何跨越鸿沟?