1.Comparable详解

1.1Comparable概述

来自java.lang.Comparable。Comparable是 排序接口。若一个类实现了Comparable接口,就意味着该类支持排序。实现了Comparable接口的类的对象的列表或数组可以通过Collections.sortArrays.sort进行自动排序。
此外,实现此接口的对象可以用作有序映射中的键或有序集合中的集合,无需指定比较器。
此 接口只有一个方法compareTo,比较此对象与指定对象的顺序,如果该对象小
于、等于或大于指定对象,则分别返回负整数、零或正整数。

对于String类实现了这个Comparable接口(Integer也实现这接口)进行升序排列,并完成了比较规则的定义,但是这样就把这种规则写死了,那比如我想要字符串按照第一个字符降序排列,那么这样就要修改String的源代码,修改源码这件事这是不可能的了!,
例子:

package untl;
import java.util.Arrays;
public class MyComparable {public static void main(String[] args) {String arr[]={"aaa","bbb","ccc","ttt","ddd"};jiuArrays.sort(arr);for (String str:arr) {System.out.println(str);}}
}
运行结果:
aaa
bbb
ccc
ddd
ttt

但是如果是我们自定义的类,我们可以重写comepareTo()方法,再利用工具类进行排序,这样按照我们想要的方式进行排序:

package untl;
import java.util.Arrays;
public class MyComparable {public static void main(String[] args) {student stu[]={new student("张三",14),new student("李四",19),new student("王五",17)};Arrays.sort(stu);for (student s: stu) {System.out.println(s);}}
}
class student implements Comparable<student>{private String name;private int age;public student(String name,int age){this.age=age;this.name=name;}public int compareTo(student stu){if(stu.age<this.age)return 1;//意思是按照升序排列else if(stu.age>this.age)return -1;elsereturn 0;}//  public int compareTo(student stu)// {//  return this.age-stu.age;//  }//上述两个compareTo等效public String toString(){return "姓名"+this.name+"  年龄"+this.age;}}
运行结果:
姓名张三  年龄14
姓名王五  年龄17
姓名李四  年龄19

这里博主讲一下compareTo()返回值的意义:

JDK官方默认是升序

对于这段代码

   return this.age-stu.age;

其实这段代码等价于:

if (this.age-stu.age>0)return 1;else if(this.age-stu.age<0)return -1;elsereturn  0;

那么如果你修改了代码;

 if (this.age-stu.age>0)return -1;else if(this.age-stu.age<0)return 1;elsereturn  0;

就会把默认的升序排列变成降序排列
当然降序排列也可以这么写

   return stu.age-this.age;

其实返回值1的意思是两比较对象需要在最初的位置上交换位置,返回-1,0代表排序的时候两比较对象最初位置不需要交换,什么意思:

package untl;
import java.util.Arrays;
public class MyComparable {public static void main(String[] args) {student stu[]={new student("张三",19),new student("李四",14),};for (student s: stu) {System.out.println(s);}Arrays.sort(stu);for (student s: stu) {System.out.println(s);}}
}
class student implements Comparable<student>{private String name;private int age;public student(String name,int age){this.age=age;this.name=name;}public int compareTo(student stu){if (this.age-stu.age>0)return 1;else if(this.age-stu.age<0)return -1;elsereturn  0;}public String toString(){return "姓名"+this.name+"  年龄"+this.age;}}
运行结果:
姓名张三  年龄19
姓名李四  年龄14
姓名李四  年龄14
姓名张三  年龄19

张三的最初位置为0,李四为1,那么由于返回值为1,所以两者交换位置,这就是实现排序的基础,其实返回值1可以替换成一个大于的数就,-1同样可以替换成小于0的数,,正负值只是代表两数大小的判断

总的来说:Comparable强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo方法被称为它的自然比较方法。只能在类中实现compareTo()一次,不能经常修改类的代码实现自己想要的排序.,比如上述我们要按照降序排列的话就必须从新修改方法里边的源码
总之:
comparable是需要比较的对象来实现接口。这样对象调用实现的方法来比较。对对象的耦合度高(需要改变对象的内部结构,破坏性大)

2.Comparator详解

2.1Comparator简介

强行对某个对象进行整体排序。可以将Comparator 传递给sort方法(如Collections.sortArrays.sort),从而允许在排序顺序上实现精确控制。还可以使用Comparator来控制某些数据结构(如有序set或有序映射)的顺序,或者为那些没有自然顺序的对象collection提供排序。
我们如果需要控制某个类的次序,而该类本身不支持排
序(即没有实现Comparable接口),那么我们就可以建立一个“该类的比较器”来进行排
序,这个“比较器”只需要实现Comparator接口即可。也就是说,我们可以通过实现
Comparator来新建一个比较器,然后通过这个比较器对类进行排序。

2.2Comparator注意点

1.若一个类要实现Comparator接口:它一定要实现compare(T o1, T o2)函数,但
可以不实现equals(Object obj)函数。
2.int compare(T o1, T o2) 是“比较o1和o2的大小”。返回“负数”,意味着“o1比o2
小”;返回“零”,意味着“o1等于o2”;返回“正数”,意味着“o1大于o2”。
例子:

package untl;
import java.util.Arrays;
import java.util.Comparator;public class MyComparable {public static void main(String[] args) {student stu[]={new student("张三",19),new student("李四",14),};for (student s: stu) {System.out.println(s);}Arrays.sort(stu,new Comparator<student>(){public int compare(student o1, student o2){return o1.getage()-o2.getage();//升序}});for (student s: stu) {System.out.println(s);}}
}
class student  {private String name;private int age;public student(String name,int age){this.age=age;this.name=name;}public String toString(){return "姓名"+this.name+"  年龄"+this.age;}public int getage(){return age;}}
运行结果:
姓名张三  年龄19
姓名李四  年龄14
姓名李四  年龄14
姓名张三  年龄19

同样的compare里边的实现依然可以换成return 1 ,return -1的形式;

**>注意Comparator接口不是排序接口,我们必须要在Arrays或者Collections传递两个参数,第一个参数是集合或者数组,第二个参数则是比较器Comparator(定义比较规则)

Comparable接口和Comparator接口的比较

1.Comparable是排序接口,若一个类实现了Comparable接口,就意味着“该类支持
排序”。Comparator是比较器,我们若需要控制某个类的次序,可以建立一个“该类的
比较器”来进行排序。Comparable相当于“内部比较器”,而Comparator相当于“外部比
较器”。

2.用Comparable简单, 只要实现Comparable 接口的对象直接就成为一个可以比较
的对象,但是需要修改源代码。 用Comparator 的好处是不需要修改源代码, 而是另
外实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传
递过去就可以比大小了, 并且在Comparator 里面用户可以自己实现复杂的可以通用
的逻辑,使其可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了。
3.comparable接口实际上是出自java.lan包,它有一个compareTo(Object obj)方法用来排序
comparator接口实际上是出自java.util 包,它有一个compare(Object obj1, Object obj2)方法用来排序
4.一般我们需要对一个集合使用自定义排序时,我们就要重写compareTo方法或compare方法,当我们需要对某一个集合实现两种排序方式,比如一个song对象中的歌名和歌手名分别采用一种排序方法的话,我们可以重写compareTo方法和使用自制的Comparator方法或者以两个Comparator来实现歌名排序和歌星名排序,第二种代表我们只能使用两个参数版的Collections.sort().

Comparable接口和Comparator接口的比较相关推荐

  1. Java基础之Comparable接口和Comparator接口的比较

    前言 就是普普通通的写这么一篇文章,java集合类估计java程序猿都知道,那就写一点小众的. 在实际应用中,我们往往有需要比较两个自定义对象大小的地方.而这些自定义对象的比较,就不像简单的整型数据那 ...

  2. Comparable接口和Comparator接口

    目录 1 介绍 2 Comparable接口 3 Comparator接口 4 总结 1 介绍 有这样2个人,一个人光头,一个人有黑色头发,现在不允许染发,只允许光头的带假发,理由是有头发的人没有必要 ...

  3. Java6.0中Comparable接口与Comparator接口详解

    Java6.0中Comparable接口与Comparator接口详解 说到现在,读者应该对Comparable接口有了大概的了解,但是为什么又要有一个Comparator接口呢?难道Java的开发者 ...

  4. 深入理解 Comparable 接口和 Comparator 接口以及Arrays.sort()

    compareTo(Object o)方法是java.lang.Comparable<T>接口中的方法,当需要对某个类的对象进行排序时,该类需要实现Comparable<T>接 ...

  5. Comparable接口和Comparator接口的使用和区别

    Comparable Comparable接口在JDK8中的源码: package java.lang; import java.util.*;package java.lang; public in ...

  6. Java中比较对象的两个接口Comparable接口和Comparator接口

    2019独角兽企业重金招聘Python工程师标准>>> jdk文档是这样介绍的 1.  public interface  Comparable<T>:此接口强行对实现它 ...

  7. Comparable接口与Comparator接口

    [Comparable和Comparator源码] java.lang.Comparablepublic interface Comparable<T> {public int compa ...

  8. Java 中类的比较与排序方法(应用Comparable接口与Comparator接口)通俗易懂

    引言 在平时写Java的程序的时候,如果要进行一些基本类型的变量的比较,可以很方便得调用Math.max().Math.min()等方法,如果要对数组或者列表进行排序,也可以用Arrays.sort( ...

  9. java实现Comparable接口和Comparator接口,并重写compareTo方法和compare方法

    原文地址https://segmentfault.com/a/1190000005738975 实体类:java.lang.Comparable(接口) + comareTo(重写方法),业务排序类 ...

最新文章

  1. Maven 的这 7 个问题你思考过没有?
  2. ZOJ 3329 One Person Game 带环的概率DP
  3. 通过调用API函数实现的无边框窗体的拖拽,比判断坐标更快捷
  4. 走近分形与混沌(part10)--用简单的规律来描述复杂的大自然
  5. python元组元素删除_Python3基础 通过拆分元素 把元组的数据删除
  6. 容器编排技术 -- Kubernetes kubectl patch 命令详解
  7. git安装步骤_详解linux安装git的方法步骤(超实用)
  8. inno setup 打包脚本学习
  9. Oracle Database 11g Express Edition学习笔记
  10. onenote使用python开发_如何充分利用 OneNote,发挥它的全部价值和潜力?
  11. java hsqldb数据库,HSQLDB数据库的使用
  12. 《JavaScript设计模式》初次笔记——wsdchong
  13. woff文件 服务器上找不到,vue Iview 项目部署到服务器上woff2文件 net::ERR_ABORTED 404 (Not Found)怎么处理?...
  14. 摄影构图学83年绝版_让模特露肩、露腿的摄影师们,我求求你别再祸害“古风摄影”了!...
  15. 正则表达式测试工具使用说明
  16. android手机 无电池开机,手机无法开机的6种解决方法
  17. 横向打印二叉树 java_按树状横向打印二叉树
  18. Post 和 Get方法
  19. 如何使IOT2050成为PN设备
  20. eclipse+装android+studio,EclipseAndroid Studio安装教程

热门文章

  1. 分析Linux内核5.0系统调用处理过程
  2. 如何多快好省的建设企业级呼叫中心(一)
  3. .NET 环境中使用RabbitMQ
  4. SQL Server跨库查询
  5. C++ TypeId简介与使用
  6. java-基础练习题3
  7. Flex数据绑定陷阱(一)
  8. 探究platform_driver中“多态”思想
  9. react中axios的二次封装
  10. docker run指定entrypiont