//Comparable 接口强行对实现它的每个类的对象进行整体排序。 -- 自然排序。类的compareTo称为自然比较方法。

public interface Comparable<T> {
public int compareTo(T o);
}

  此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。

  实现此接口的对象列表(和数组)可以通过 Collections.sort(和 Arrays.sort)进行自动排序。实现此接口的对象可以用作有序映射(接口 java.util.SortedMap<K,V>)中的键或有序集合(接口 java.util.SortedSet<E>)中的元素,无需指定比较器(接口 java.util.Comparator<T>)。

compareTo 方法的返回值有三种情况:

  1. e1.compareTo(e2) > 0 即 e1 > e2
  2. e1.compareTo(e2) = 0 即 e1 = e2
  3. e1.compareTo(e2) < 0 即 e1 < e2

注意:

1.由于 null 不是一个类,也不是一个对象,因此在重写 compareTo 方法时应该注意 e.compareTo(null) 的情况,即使 e.equals(null) 返回 false,compareTo 方法也应该主动抛出一个空指针异常 NullPointerException。

2.Comparable 实现类重写 compareTo 方法时一般要求 e1.compareTo(e2) == 0 的结果要和 e1.equals(e2) 一致。这样将来使用 SortedSet 等根据类的自然排序进行排序的集合容器时可以保证保存的数据的顺序和想象中一致。

接口实现的例子:

import java.util.ArrayList;
import java.util.Collections; public class Car implements Comparable<Object>{
public String name;
public int price; public Car(String name, int price){
this.name = name;
this.price = price;
} public String toString() {
return this.name + ":" + this.price;
} @Override
public int compareTo(Object o) {
if ( o instanceof Car) {
Car car = (Car)o;
int result; result = this.price - car.price;
// 当car的price相同时,比较其name,按String的comparaTo()方法排序
if (result == 0) {
result = this.name.compareTo(car.name);
}
return result;
}
return 0;
} public static void main(String[] args) {
ArrayList<Car> all = new ArrayList<Car>();
all.add(new Car("兰博基尼", 400));
all.add(new Car("宝马", 100));
all.add(new Car("奔驰", 95));
all.add(new Car("法拉利", 300)); System.out.println(all);
Collections.sort(all);
System.out.println(all);
} }

打印出:

[兰博基尼:400, 宝马:100, 奔驰:95, 法拉利:300]
[奔驰:95, 宝马:100, 法拉利:300, 兰博基尼:400]

Comparator 比较器接口(策略设计模式)

  我们如果需要控制某个类的次序,而该类本身不支持排序(即没有实现Comparable接口);那么可以建立一个该类的比较器来排序,这个比较器只需要实现Comparator接口即可。

public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
}

使用方式主要分三步:

1.创建一个 Comparator 接口的实现类,并赋值给一个对象在 compare 方法中针对自定义类写排序规则

2.将 Comparator 对象作为参数传递给 排序类的某个方法

3.向排序类中添加 compare 方法中使用的自定义类

接口操作例子:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator; public class Car {
public String name;
public int price; public Car(String name, int price){
this.name = name;
this.price = price;
} public String toString() {
return this.name + ":" + this.price;
}
public static void main(String[] args) {
ArrayList<Car> all = new ArrayList<Car>();
all.add(new Car("兰博基尼", 400));
all.add(new Car("宝马", 100));
all.add(new Car("奔驰", 95));
all.add(new Car("法拉利", 300)); System.out.println(all);
Collections.sort(all, new MyComparator());
System.out.println(all); } } class MyComparator implements Comparator<Car> { @Override
public int compare(Car o1, Car o2) {
// TODO Auto-generated method stub
int result = o1.price - o2.price;
if ( result != 0) {
return result;
} else {
return o1.name.compareTo(o2.name);
}
} }

打印出:

[兰博基尼:400, 宝马:100, 奔驰:95, 法拉利:300]
[奔驰:95, 宝马:100, 法拉利:300, 兰博基尼:400]

Comparable 和 Comparator比较

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

前者应该比较固定,和一个具体类相绑定,而后者比较灵活,它可以被用于各个需要比较功能的类使用。可以说前者属于 “静态绑定”,而后者可以 “动态绑定”。

我们不难发现:Comparable 相当于 “内部比较器”,而 Comparator 相当于 “外部比较器”。

java lang(Comparable接口) 和java util(Comparator接口)分析比较的更多相关文章

  1. Java.lang.Comparable接口和Java.util.Comparator接口的区别

    Java的Comparator和Comparable当需要排序的集合或数组不是单纯的数字型时,通常可以使用Comparator或Comparable,以简单的方式实现对象排序或自定义排序. 1.Com ...

  2. java.lang.Comparable接口

    转自:http://blog.csdn.net/zccst/article/details/5092920 java.lang.Comparable 接口 作者: zccst java.lang.Co ...

  3. Java基础 TreeSet()来实现数组的【定制排序】 : Comparable接口(自然排序) 或者 Comparator接口 (定制排序)

    笔记: //排序真麻烦!没有C++里的好用又方便!ORZ!ORZ!数组排序还还自己写个TreeSet()和( Comparable接口(自然排序) 或者 Comparator接口 (定制排序))imp ...

  4. TreeMap cannot be cast to java.lang.Comparable

    /** * Constructs a new, empty tree map, using the natural ordering of its * keys. All keys inserted ...

  5. Cannot be cast to java.lang.Comparable异常

    Set集合中的treeSet问题:cannot be cast to java.lang.Comparable: 原理: Set不保存重复的元素,与Collection类似,只是行为不同,Set是基于 ...

  6. cannot be cast to java.lang.Comparable

    Exception in thread "main" java.lang.ClassCastException: com.myradio.People cannot be cast ...

  7. Set集合中的treeSet问题:cannot be cast to java.lang.Comparable;

    使用TreeSet保存自定义对象时, 必须让定义对象的类实现Comparable接口,并重写compareTo()方法 否则报 实体类User:cannot be cast to java.lang. ...

  8. java.lang.NoSuchMethodError: org.apache.tomcat.util.res.StringManager.getManager(Ljava/lang/Class;)Lorg/apache/tomcat/util/res/StringManager

    问题: 使用Springboot打包为war部署于Tomcat7中报错 java.lang.NoSuchMethodError: org.apache.tomcat.util.res.StringMa ...

  9. maven web 项目中启动报错java.lang.ClassNotFoundException: org.springframework.web.util.Log4jConfigListener

    环境:Groovy/Grails Tool Suite 3.1.0.RELEASE(BASED ON ECLIPSE JUNO 3.8.1).JDK1.6.Maven3.05.Tomcat6 错误描述 ...

  10. maven web启动报错java.lang.ClassNotFoundException: org.springframework.web.util.Log4jConfigListener

    问题描述 SEVERE: Error configuring application listener of class org.springframework.web.util.Log4jConfi ...

随机推荐

  1. 现在使用Nginx实现TCP反向代理

    Nginx 在1.9.0版本发布以前如果要想做到基于TCP的代理及负载均衡需要通过打名为 nginx_tcp_proxy_module 的第三方patch来实现,该模块的代码托管在github上网址: ...

  2. Error response from daemon:###unable to delete ### (must be forced) - image is being used by stopped

    具体错误:Error response from daemon: conflict: unable to delete f2e2f7b8308b (must be forced) - image is ...

  3. Linux配置本地yum源

    最近在配置zabbix时,遇到CentOS 无法连接网络问题,搜索到一种配置本地yum源的方法,特此记录 一.联网安装预处理 配置缓存,修改/etc/yum.conf [main] cachedir= ...

  4. [2] LabelImg图片标注 与 YOLOv3 网络训练 (待补充)

    LabelImg是一个图形图像注释工具. 它是用Python编写的,并使用Qt作为其图形界面. 注释以PASCAL VOC格式保存为XML文件,这是ImageNet使用的格式.Besdies,它也支持 ...

  5. 【转】java将excel文件转换成txt格式文件

    在实际应用中,我们难免会遇到解析excel文件入库事情,有时候为了方便,需要将excel文件转成txt格式文件.下面代码里面提供对xls.xlsx两种格式的excel文件解析,并写入到一个新的txt文 ...

  6. redis单例模式写法

    <?php /**只看红色重点 * =========================================================== * ZW_Memory_Cache * ...

  7. robotframework中的try exception。断言失败后,后面语句能继续执行

    1.在robot中,断言有时会失败,但不想影响后面语句的执行,这时候要用到 Run Keyword And Continue On Failure

  8. Linux如何查看端口状态

    netstat命令各个参数说明如下: -t : 指明显示TCP端口 -u : 指明显示UDP端口 -l : 仅显示监听套接字(所谓套接字就是使应用程序能够读写与收发通讯协议(protocol)与资料的 ...

  9. Git基础使用教程

    Git是一个开源的分布式版本控制系统,可以有效.高速的处理从很小到非常大的项目版本管理,是目前使用范围最广的版本管理工具. 之前的博客中介绍了linux下安装Git的内容,这篇博客,简单介绍下使用Gi ...

  10. Redis学习之底层链表源码分析

    Redis底层链表的源码分析: 一.链表结点的结构(单个结点): // listNode 双端链表节点 typedef struct listNode { // 前置节点 struct listNod ...