一、定制排序:java.util.Comparator 接口

  强行对某个对象 collection 进行整体排序 的比较函数。可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用 Comparator 来控制某些数据结构(如有序 set或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。

  当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用 Comparator 的对象来排序。

java.util.Comparator<T>接口:
抽象方法:int compare(T o1, T o2)

  <T> 是泛型,可以理解成 Object。

  java.util.Comparator接口:

    抽象方法:int compare(Object o1, Object o2)

  说明:这个接口是代表 Java 中比较两个对象的大小标准。而且是一种“定制”比较的标准。

     这个接口中没有规定如何比较两个对象的大小。

     但是规定了:如果认为 o1 大于 o2,那么就返回正整数表示;

           如果认为 o1 小于 o2,那么就返回负整数表示;

           如果认为 o1 等于 o2,那么就返回0表示;

  需求:声明一个学生类,实现 comparator 接口,来定制两个学生比较的具体实现方式

  Demo:

  学生类:

 class Student{
private String name;
private int age;
private int score;
public Student(String name, int age, int score) {
super();
this.name = name;
this.age = age;
this.score = score;
}
public Student() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", score=" + score + "]";
} }

  测试类:

 public class TestComparator {
public static void main(String[] args) {
Student s1 = new Student("小李子", 25, 89);
Student s2 = new Student("小张字", 24, 99); AgeComparator c = new AgeComparator();
if(c.compare(s1, s2) > 0){ //如果比较s1,s2的结果是正整数,说明s1>s2
System.out.println("s1 > s2的年龄");
}else if(c.compare(s1, s2) <0){
System.out.println("s1 < s2的年龄");
}else{
System.out.println("s1 = s2的年龄");
} Student[] all = new Student[5];
all[0] = s1;
all[1] = s2;
all[2] = new Student("张三",22,87);
all[3] = new Student("李四",24,44);
all[4] = new Student("王五",25,45); //Arrays工具类
//Arrays.sort(all);
/*
* public static void sort(Object[] a, Comparator c)
* 第一个形参:需要排序的数组,Object[]说明可以是任意类型的对象数组
* 第二个形参:比较器对象 Comparator接口不能创建对象,只能传入实现类对象
*/
Arrays.sort(all, new AgeComparator()); for (int i = 0; i < all.length; i++) {
System.out.println(all[i]);
}
}
} //实现Comparator接口,来定制两个学生比较的具体实现方式
//例如:按照年龄比较
class AgeComparator implements Comparator{ @Override
public int compare(Object o1, Object o2) {
//(1)向下转型
Student s1 = (Student) o1;
Student s2 = (Student) o2; //(2)开始比较
if(s1.getAge() > s2.getAge()){
return 1;
}else if(s1.getAge() < s2.getAge()){
return -1;
}
return 0;
} }

二、自然排序:java.lang.Comparable 接口

  Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo(T t) 方法被称为它的自然比较方法。当前对象this与指定对象t比较“大小”,如果当前对象this大于指定对象t,则返回正整数,如果当前对象this小于指定对象t,则返回负整数,如果当前对象this等于指定对象t,则返回零。

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

  Comparable 的典型实现:

String:按照字符串中字符的Unicode值进行比较

Character:按照字符的Unicode值来进行比较

数值类型对应的包装类以及BigInteger、BigDecimal:按照它们对应的数值大小进行比较

Date、Time等:后面的日期时间比前面的日期时间大

java.lang.Comparable:自然比较,自然顺序
int compareTo(Object obj)

  this 与 obj 对象比较,this > obj,返回正整数;

  this 与 obj 对象比较,this < obj,返回负整数;

  this 与 obj 对象比较,this = obj,返回0;   

 对于上面的案例来说,如果希望学生对象本身就具备比较大小的能力。可以使学生实现 Comparable 接口。

 代码:

 public class TestComparable {
public static void main(String[] args) {
Student s1 = new Student("小李子", 25, 89);
Student s2 = new Student("小张字", 24, 99); //按成绩比较
if(s1.compareTo(s2)>0){
System.out.println("s1 > s2成绩");
}else if(s1.compareTo(s2)<0){
System.out.println("s1 < s2成绩");
}else{
System.out.println("s1 = s2成绩");
} }
}
class Student implements Comparable{
private String name;
private int age;
private int score;
public Student(String name, int age, int score) {
super();
this.name = name;
this.age = age;
this.score = score;
}
public Student() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", score=" + score + "]";
}
@Override
public int compareTo(Object obj) {
//this与obj比较,this和obj都是学生对象
Student other = (Student) obj;
//例如:对于学生对象来说,最常用的是按成绩排名,那么我就可以把自然顺序定位成绩升序
/* if(this.score > other.score){
return 1;
}else if(this.score < other.score){
return -1;
}
return 0;*/ return this.score - other.score;
}
}

  总结:

    Arrays 的 sort 方法有两种:

   (1)void sort(Object[] arr)

       根据元素的自然顺序对指定对象数组按升序进行排序,数组中的所有元素必须实现 Comparable 接口

   (2)void sort(Object[] arr, Comparator c)

       根据“指定比较器”产生的顺序对指定对象数组进行排序,数组中的所有元素都必须是通过“指定比较器”可相互比较的。

Java 之 比较器( Comparator接口与 Comparable 接口)的更多相关文章

  1. Java:实现对象的比较 comparable接口和comparator接口

    在实际应用中,我们往往有需要比较两个自定义对象大小的地方.而这些自定义对象的比较,就不像简单的整型数据那么简单,它们往往包含有许多的属性,我们一般都是根据这些属性对自定义对象进行比较的.所以Java中 ...

  2. Java—集合框架 Collections.sort()、Comparable接口和Comparator接口

    Collentions工具类--java.util.Collections Collentions是Java集合框架中,用来操作集合对象的工具类,也是Java集合框架的成员,与List.Map和Set ...

  3. Java Comparator方法 和 Comparable接口

    默认的排序方法: 让类继承Comparable接口,重写compareTo方法. 示例代码: package com.imooc.collection; import java.util.HashSe ...

  4. Java中Comparator接口和Comparable接口的使用

    普通情况下在实现对对象元素的数组或集合进行排序的时候会用到Comparator和Comparable接口,通过在元素所在的类中实现这两个接口中的一个.然后对数组或集合调用Arrays.sort或者Co ...

  5. comparator接口与Comparable接口的区别

    1. Comparator 和 Comparable 相同的地方 他们都是java的一个接口, 并且是用来对自定义的class比较大小的, 什么是自定义class: 如 public class Pe ...

  6. 关于comparator接口和comparable接口以及它们各自的方法compare()和compareTo()

    在今天做的LeetCode的题中有两道都出现了利用接口实现对象的排序.两题的相关链接: 1.利用comparable接口对对象排序 2.利用comparator接口实现排序 因为之前都没接触过这两个接 ...

  7. comparator接口与Comparable接口的差别

    1. Comparator 和 Comparable 同样的地方 他们都是java的一个接口, 而且是用来对自己定义的class比較大小的, 什么是自己定义class: 如 public class  ...

  8. Java基础--比较器Comparator

    Comparable接口和Comparator接口都是用来定义集合中的排序的,只是Comparable是在集合内部定义排序的实现,Comparator是在集合外部排序的实现. Comparable 的 ...

  9. 实现Comparator接口和Comparable接口,以及Map按value排序 ,map遍历

    继承Comparator接口,重写compare()方法 import java.util.ArrayList; import java.util.Arrays; import java.util.C ...

随机推荐

  1. 装ubuntu的坑

    装ubuntu安装盘的U盘,在BOOT中会出现两种载入方式,切记不要用UEFI方式打开,否则安装ubuntu会在最后卡在GRUB的安装上面,然后失败.

  2. hdu5285-wyh2000 and pupil-(染色法二分图判定)

    http://acm.hdu.edu.cn/showproblem.php?pid=5285 题意:把互不认识的人分到两个组,第一组人数尽可能多. 题解:把互不认识的人连起来,当作二分图,二分图可能有 ...

  3. NOIP2013-2014提高组题目浅析

    1.前言 迎接NOIP的到来...在这段闲暇时间,决定刷刷水题.这里只是作非常简单的一些总结. 2.NOIP2014 <1> 生活大爆炸之石头剪刀布(模拟) 这是一道考你会不会编程的题目. ...

  4. NOIP动态规划大合集

    1.前言 NOIP2003-2014动态规划题目大合集,有简单的也有难的(对于我这种动态规划盲当然存在难的),今天就把这些东西归纳一下,做一个比较全面的总结,方便对动态规划有一个更深的理解. 2.NO ...

  5. luogu p2622关灯问题II

    luogu p2622关灯问题II 题目描述 现有n盏灯,以及m个按钮.每个按钮可以同时控制这n盏灯--按下了第i个按钮,对于所有的灯都有一个效果.按下i按钮对于第j盏灯,是下面3中效果之一:如果a[ ...

  6. 微软SQL Server 2019 全新发布,更新内容亮点都在这里了

    IT之家11月7日消息 在Microsoft   Ignite 2019 大会上,微软正式发布了新一代数据库产品SQL Server 2019.使用统一的数据平台实现业务转型SQL Server 20 ...

  7. concurrent(六)同步辅助器CyclicBarrier & 源码分析

    参考文档:Java多线程系列--“JUC锁”10之 CyclicBarrier原理和示例:https://www.cnblogs.com/skywang12345/p/3533995.html简介Cy ...

  8. 20165313-bof进阶

    实践基础知识 1.ALSR 1.定义: ASLR,全称为 Address Space Layout Randomization,地址空间布局随机化,它将进程的某些内存空间地址进行随机化来增大入侵者预测 ...

  9. Gamma阶段第七次scrum meeting

    每日任务内容 队员 昨日完成任务 明日要完成的任务 张圆宁 #91 用户体验与优化https://github.com/rRetr0Git/rateMyCourse/issues/91(持续完成) # ...

  10. 【Activiti学习之一】Activiti入门

    环境 JDK1.7 MySQL5.6 Tomcat7 Eclipse-Luna activiti 6.0 一.概念1.工作流(Workflow):是一系列相互衔接.自动进行的业务活动或任务.采用工作流 ...