简介:

Comparable接口出自java.lang包,它有一个compareTo(Object obj)方法用来比较或排序
Comparator接口出自java.util包,它有一个compare(Object obj1、Object obj2)方法用来排序。

当我们需要对集合进行自定义排序或对象之间进行比较时,就需要重写compareTo()或者compare()方法。


Comparable:

Comparable是一个对象支持自比较所需要实现的接口,如String、Integer自己就实现了Comparable接口,我们可以直接用他们的CompareTo()方法来比较,或者直接对List<String>或List<Integer>集合进行排序。
例如:

String s1 = "abc";
String s2 = "aba";
System.out.println(s1.compareTo(s2)); // 2
List<String> list = new ArrayList<>();
list.add("abc");
list.add("ab");
list.add("dde");
Collections.sort(list);for (String s : list) {System.out.println(s);
}

而我们自定义的类如果想进行比较,或者放入list中进行排序,则需要实现Comparable接口的compareTo方法,这样才支持比较或者排序。否则我们直接调用Collections.sort(list)会出现编译错误的。比如我们有一个Person类,两个属性姓名和年龄,想让List<Person>通过年龄来排序:

public class Person implements Comparable<Person>{private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return this.name;}public void setName(final String name) {this.name = name;}public int getAge() {return this.age;}public void setAge(final int age) {this.age = age;}@Overridepublic int compareTo(Person o) {if(this.age == o.getAge() && this.name == o.getName()){return 0;}else if(this.age > o.getAge()){return 1;}else{return -1;}}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}
}
import JavaTest.compare.Person;
import org.junit.Test;
import java.util.*;public class Test1 {@Testpublic void testComparable() {List<Person> list = new ArrayList<>();Person person1 = new Person("张三",22);Person person2 = new Person("李四",29);Person person3 = new Person("王五",42);list.add(person1);list.add(person2);list.add(person3);// 实现comparable接口就会自动调用compareTo进行排序Collections.sort(list);for (Person p: list) {System.out.println(p);}//比较System.out.println(person1.compareTo(person2));}
}


Comparator:

Comparator是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足要求时(比如二维数组排序,后面会讲到),可写一个比较器来完成两个对象之间大小的比较,或者集合排序。
例如:一个User类,同样有年龄和姓名属性,我们想对List排序,但User类没有实现Comparable接口,假定User类我们不能修改,此时我们可以用Comparator来实现。

public class User {private String name;private int age;public User(String name, int age) {this.name = name;this.age = age;}public String getName() {return this.name;}public void setName(final String name) {this.name = name;}public int getAge() {return this.age;}public void setAge(final int age) {this.age = age;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}
}
@Test
public void testComparator() {List<User> list = new ArrayList<>();User user1 = new User("张三",22);User user2 = new User("李四",29);User user3 = new User("王五",42);list.add(user1);list.add(user2);list.add(user3);Collections.sort(list, new Comparator<User>() {@Overridepublic int compare(User o1, User o2) {if(o1.getAge() == o2.getAge() && o1.getName() == o2.getName()){return 0;}else if(o1.getAge() > o2.getAge()){return 1;}else{return -1;}}});for (User u: list) {System.out.println(u);}}

我们这里通过匿名类的形式new Comparator<User>() 来实现list集合的排序,当然我们也可以再定义一个UserComparator类来实现Comparator接口,然后通过 UserComparator uc = new UserComparator(); Collections.sort(list, uc); 来实现。

由这两个例子看出Comparable是类的内部实现比较或排序功能,Comparator是外部实现的。

二维数组排序:
另外举个例子,二维数组排序,按照某一列列大小对数组进行排序。二维数组的排序直接调用Arrays.sort(); 虽然不会出现编译错误,但运行时会出现以下错误提示:

说明不可以这样用,而我们又想对它排序,就可以使用Comparator来外部实现排序了,这里举一个按照第二列数字大小进行排序的例子:

public class ArrayCompare {public static void main(String[] args) {int[][] arr = new int[4][2];System.out.println("产生的二维数组arr为:");for (int i = 0; i < 4; i++) {arr[i][0] = (int)(Math.random()*10 + 1);arr[i][1] = (int)(Math.random()*10 + 2);System.out.println(Arrays.toString(arr[i]));}//arr2拷贝一份arr的值,这里没什么意义,就简单使用一下cloneint[][] arr2 = new int[4][2];arr2 = arr.clone();//arr以第二列值大小排序Arrays.sort(arr2, new Comparator<int[]>() {@Overridepublic int compare(int[] t0, int[] t1) { // t0与t1类似于两个对象进行比较,这里表示两个一维数组,即二维数组的两行if(t0[1] == t1[1]){return t0[0]-t1[0]; //第二列中的值相同时,再比较第一列的大小,如果不需要也可以直接return 0}return t0[1] - t1[1];}});System.out.println("arr自定义排序为:");showArray(arr2);}public static void showArray(int[][] arr){for (int[] row : arr) {System.out.println(Arrays.toString(row));}}
}


Comparable与Comparator用法详解相关推荐

  1. Java创建comparator对象,Java Comparable 和 Comparator 的详解及区别

    Java Comparable 和 Comparator 的详解及区别 Java 中为我们提供了两种比较机制:Comparable 和 Comparator,他们之间有什么区别呢?今天来了解一下. C ...

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

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

  3. Java(enum)枚举用法详解

    转载自 Java(enum)枚举用法详解 本篇文章主要介绍了Java 枚举用法详解,枚举的好处:可以将常量组织起来,统一进行管理.有兴趣的可以一起来了解一下. 概念 enum的全称为 enumerat ...

  4. java 枚举类型enum的用法详解

    Java Enum原理 public enum Size{ SMALL, MEDIUM, LARGE, EXTRA_LARGE }; 实际上,这个声明定义的类型是一个类,它刚好有四个实例,在此尽量不要 ...

  5. java的sort的用法_Java排序方法sort用法详解

    Java排序方法sort用法详解 发布于 2020-2-28| 复制链接 摘记: 本文实例为大家分享了java对数组.集合的排序方法,供大家参考,具体内容如下对数组的排序: ```java //对数组 ...

  6. java中String的用法详解

    在这里先分别对String.StringBuffer.StringBuilder进行解析,在比较三者异同 String String类:代表字符串.Java程序中所有的字符串字面值(如"fd ...

  7. python argv 详解_Python3 sys.argv[ ]用法详解

    sys.argv[]说白了就是一个从程序外部获取参数的桥梁,这个"外部"很关键,因为我们从外部取得的参数可以是多个,所以获得的是一个列表(list),也就是说sys.argv其实可 ...

  8. oracle中的exists 和 not exists 用法详解

    from:http://blog.sina.com.cn/s/blog_601d1ce30100cyrb.html oracle中的exists 和 not exists 用法详解 (2009-05- ...

  9. ROW_NUMBER() OVER()函数用法详解 (分组排序 例子多)

    ROW_NUMBER() OVER()函数用法详解 (分组排序 例子多) https://blog.csdn.net/qq_25221835/article/details/82762416 post ...

最新文章

  1. Laravel Composer 命令大全
  2. c语言程序降低图像分辨率,减少OpenCV读取高分辨率图像的时间示例
  3. python定时发送微信消息_Python3 itchat实现微信定时发送群消息的实例代码
  4. 开始把一些东西放到博客上
  5. import package怎么用
  6. iphone连不上微软服务器,windows没法连接到iphone是什么意思
  7. lua搭建ui_LTUI, 一个基于 lua 的跨平台字符终端 UI 界面库
  8. Centos 7 离线安装dos2unix-7.4.0-3.el8.x86_64.rpm
  9. 全彩控制器的编程软件有哪些_可编程LED控制器-MINI全彩控制器软件(DC-Color)v1.08 官方版-腾牛下载...
  10. jupyter notebook报错500 : Internal Server Error
  11. 领域驱动设计DDD:贫血模型和充血模型(比较重要)
  12. Java常用环境配置(Maven、Mybatis、Spring、SpringMvc、Mybatis)
  13. 华为手机如何把计算机添加到桌面,华为手机一键锁屏添加桌面快捷方式的操作步骤...
  14. 城堡、游乐园、地下城!!!500+ 超棒 FBX 模型素材,全部都免费!
  15. 三国演义人物出场顺序统计(文本词频统计)
  16. 第4章 凯伦.霍妮——神经症需要和倾向
  17. Facebook MySQL工程师吐槽MemSQL:MySQL比你们快无数倍
  18. “云”上就诊,泽塔云超融合助力医院数字化转型
  19. pythonocc安装_PythonOCC开发-如何搭建开发环境和一个创建圆台例子
  20. 照明硬件基础知识(四)—— LED灯(半导体光源)工作原理及关键参数

热门文章

  1. AI基础:数据增强方法综述
  2. 当一个程序员真正掌握算法之后,会变得有多强...
  3. 如何保障一场千万级大型直播?
  4. 网易云信携手小天才电话手表 打造视频通话体验的行业标杆
  5. 栈与队列基本操作及其应用
  6. [JVM-3]Java垃圾回收(GC)机制和垃圾收集器选择
  7. Maxscript中渲染中文版Vray完成贴图(VrayCompleteMap)的方法
  8. Chmod 提升一个文件夹下所有文件(夹)的权限
  9. 对提高squid命中率的一些研究
  10. sql注入***原理