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接口实现后便不能改动。两种接口的调用方式如下:

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;
}
}
}
class DESComparator 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;
}
}
}
public static void main(String[] args) {
Apple apple1 = new Apple(1,4.8);
Apple apple2 = new Apple(2,5.9);
Apple apple3 = new Apple(3,8.5);
List<Apple> list = new ArrayList<Apple>();
list.add(apple1);
list.add(apple3);
list.add(apple2);
System.out.println("Comparable==========");
System.out.printf("this list of apples: %s\n",list);
Collections.sort(list);
System.out.printf("this list of apples: %s\n",list);
System.out.println("Comparator==========");
System.out.printf("this list of apples: %s\n",list);
Collections.sort(list,new DESComparator());
System.out.printf("this list of apples: %s\n",list);
Collections.sort(list,new AESComparator());
System.out.printf("this list of apples: %s\n",list); }
}

  上述代码存在的问题,不能在比较器中进行double类型的减法操作,因为对于值比较大的double,减法操作容易导致值的溢出,java7对每一种包装类型的比较新增了compare()方法,改造后的代码如下:

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.price,o.price);
}
@Override
public String toString() {
return "Apple{" +
"id=" + id +
", price=" + price +
'}';
}
}
class AESComparator implements Comparator<Apple>{ public int compare(Apple o1, Apple o2) {
return Double.compare(o1.price,o2.price);
}
}
class DESComparator implements Comparator<Apple>{ public int compare(Apple o1, Apple o2) {
return Double.compare(o2.price,o1.price);
}
}

  查看Double.compare的源码如下

public static int compare(double d1, double d2) {
if (d1 < d2)
return -1; // Neither val is NaN, thisVal is smaller
if (d1 > d2)
return 1; // Neither val is NaN, thisVal is larger // Cannot use doubleToRawLongBits because of possibility of NaNs.
long thisBits = Double.doubleToLongBits(d1);
long anotherBits = Double.doubleToLongBits(d2);
return (thisBits == anotherBits ? 0 : // Values are equal
(thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
1)); // (0.0, -0.0) or (NaN, !NaN)
}

java中Comparable和Comparator两种比较器的区别的更多相关文章

  1. Java中Compareable和Comparator两种比较器的区别

    Java中Compareable和Comparator两种比较器的区别 参考原文链接:https://www.cnblogs.com/ldy-blogs/p/8488138.html 1.引言 在ja ...

  2. Map集合的遍历方式以及TreeMap集合保存自定义对象实现比较的Comparable和Comparator两种方式

    Map集合的特点 1.Map集合中保存的都是键值对,键和值是一一对应的 2.一个映射不能包含重复的值 3.每个键最多只能映射到一个值上 Map接口和Collection接口的不同 Map是双列集合的根 ...

  3. Java中Comparable和Comparator接口区别分析

    Java中Comparable和Comparator接口区别分析 来源:码农网 | 时间:2015-03-16 10:25:20 | 阅读数:8902 [导读] 本文要来详细分析一下Java中Comp ...

  4. Java 中 Comparable 和 Comparator 比较

    Java 中 Comparable 和 Comparator 比较 目录: Comparable Comparator Comparable 和 Comparator比较 第二个例子 之 Compar ...

  5. Java中HashMap遍历的两种方式

    Java中HashMap遍历的两种方式 转]Java中HashMap遍历的两种方式原文地址: http://www.javaweb.cc/language/java/032291.shtml 第一种: ...

  6. java中数组复制的两种方式

    在java中数组复制有两种方式: 一:System.arraycopy(原数组,开始copy的下标,存放copy内容的数组,开始存放的下标,需要copy的长度); 这个方法需要先创建一个空的存放cop ...

  7. Java 中 Comparable 和 Comparator 比较(转)

    转自http://www.cnblogs.com/skywang12345/p/3324788.html 本文,先介绍Comparable 和Comparator两个接口,以及它们的差异:接着,通过示 ...

  8. PHP中数组合并的两种方法及区别介绍

    PHP数组合并两种方法及区别 如果是关联数组,如下: 复制代码代码如下: $a = array( 'where' => 'uid=1', 'order' => 'uid', ); $b = ...

  9. Java中Comparable和Comparator区别小结

    一.Comparable简介 Comparable是排序接口.若一个类实现了Comparable接口,就意味着该类支持排序.实现了Comparable接口的类的对象的列表或数组可以通过Collecti ...

随机推荐

  1. 查询sql表列名

    --查询sql 查询表列名Select Name FROM SysColumns Where id=Object_Id('Tab') --查询sql数据库表列名称select name from sy ...

  2. LaTeX初识 新手入门 Texlive和Texmaker学习

    转载自:http://blog.sina.com.cn/s/blog_90444ed201016iq6.html http://blog.csdn.net/zb1165048017/article/d ...

  3. 【Android Developers Training】 34. 添加一个简单的分享行为(Action)

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  4. Redux-Saga学习心得

    # Redux Saga ## 简述- Reducers负责处理action的state更新:- Sagas负责协调那些复杂或异步的操作. ## 安装 npm install --save redux ...

  5. pdf.js在国际化的时候,显示不了中文的解决办法

    在项目中使用了pdf实现在线预览功能,开始工具栏中一直都是英文的,在view.js中设置了也不起作用,偶然发现了问题所在 当我把网站发布到iis上的时候,用google浏览器的审查元素功能的审核发现j ...

  6. 一篇文章学懂Shell脚本

    Shell脚本,就是利用Shell的命令解释的功能,对一个纯文本的文件进行解析,然后执行这些功能,也可以说Shell脚本就是一系列命令的集合.Shell可以直接使用在win/Unix/Linux上面, ...

  7. setTimeout与setInterval参数之String

    今天无意中给某网友解答了一些setTimeout的问题,发现一个有趣的东西. 以前我总认为setTimeout的第一个参数只能function,后面发现string也能执行.那问题来了,String做 ...

  8. (转载)oracle 在一个存储过程中调用另一个返回游标的存储过程

    原文链接:http://www.jb51.net/article/20160.htm 实际项目当中经常需要在一个存储过程中调用另一个存储过程返回的游标,本文列举了两种情况讲述具体的操作方法. 第一种情 ...

  9. 进击的AssetBundles和它的工具们

    0x00 前言 周末的时候在家看了下去年的Unite16 LA的视频.其中一个session很有趣,是AssetBundles开发团队Reichert的一个"总结过往,畅想未来"的 ...

  10. HDU 1728 逃离迷宫(DFS)

    题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=1728 题目: 逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)  ...