欢迎访问 生活随笔!

凯发k8官方网

当前位置: 凯发k8官方网 > 编程资源 > 编程问答 >内容正文

编程问答

comparable接口和comparator接口的比较 -凯发k8官方网

发布时间:2024/10/14 编程问答 23 豆豆
凯发k8官方网 收集整理的这篇文章主要介绍了 comparable接口和comparator接口的比较 小编觉得挺不错的,现在分享给大家,帮大家做个参考.
1.1comparable概述

来自java.lang.comparable。comparable是 排序接口。若一个类实现了comparable接口,就意味着该类支持排序。实现了comparable接口的类的对象的列表或数组可以通过collections.sort或arrays.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.1comparator简介

强行对某个对象进行整体排序。可以将comparator 传递给sort方法(如collections.sort或 arrays.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(定义比较规则)

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

总结

以上是凯发k8官方网为你收集整理的comparable接口和comparator接口的比较的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得凯发k8官方网网站内容还不错,欢迎将凯发k8官方网推荐给好友。

网站地图