Java ---比较器

news/2024/11/17 5:23:06/
      我们知道基本数据类型的数据(除 boolean 类型外)需要比较大小的话,之间使用比较运算符即可,但是引用数据类型是不能直接使用比较运算符来比较大小的。那么,如何解决这个问题呢?
在 Java 中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题。
Java 实现对象排序的方式有两种:
自然排序:java.lang.Comparable
定制排序:java.util.Comparator

 

(一)自然排序 java.lang.Comparable 

    Comparable 接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的
自然排序。
     实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即通过
compareTo(Object obj) 方法的返回值来比较大小。如果当前对象 this 大于形参对象
obj,则返回正整数,如果当前对象 this 小于形参对象 obj,则返回负整数,如果当前
对象 this 等于形参对象 obj,则返回零。

 代码:

package java.lang;
public interface Comparable{int compareTo(Object obj);
}
实现 Comparable 接口的对象列表(和数组)可以通过 Collections.sort 或 Arrays.sort 进行自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中 的元素,无需指定比较器。
对于类 C 的每一个 e1 和 e2 来说,当且仅当 e1.compareTo(e2) == 0 与 e1.equals(e2) 具有相同的 boolean 值时,类 C 的自然排序才叫做与 equals 一致。
建议(虽然不是必需的) 最好使自然排序与 equals 一致
Comparable 的典型实现:( 默认都是从小到大排列的 )
String:按照字符串中字符的 Unicode 值进行比较
Character:按照字符的 Unicode 值来进行比较
数值类型对应的包装类以及 BigInteger、BigDecimal:按照它们对应的数值
大小进行比较
Boolean:true 对应的包装类实例大于 false 对应的包装类实例
Date、Time 等:后面的日期时间比前面的日期时间大
代码:
package com.atguigu.api;
public class Student implements Comparable {private int id;private String name;private int score;private int age;public Student(int id, String name, int score, int age) {this.id = id;this.name = name;this.score = score;this.age = age;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getScore() {return score;}public void setScore(int score) {this.score = score;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", score=" + score +", age=" + age +'}';}@Overridepublic int compareTo(Object o) {//这些需要强制,将 o 对象向下转型为 Student 类型的变量,才能调用 Stu
dent 类中的属性//默认按照学号比较大小Student stu = (Student) o;return this.id - stu.id;}
}

测试类:

package com.atguigu.api;
public class TestStudent {public static void main(String[] args) {Student[] arr = new Student[5];arr[0] = new Student(3,"张三",90,23);arr[1] = new Student(1,"熊大",100,22);arr[2] = new Student(5,"王五",75,25);arr[3] = new Student(4,"李四",85,24);arr[4] = new Student(2,"熊二",85,18);//单独比较两个对象System.out.println(arr[0].compareTo(arr[1]));System.out.println(arr[1].compareTo(arr[2]));System.out.println(arr[2].compareTo(arr[2]));System.out.println("所有学生:");for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}System.out.println("按照学号排序:");for (int i = 1; i < arr.length; i++) {for (int j = 0; j < arr.length-i; j++) {if(arr[j].compareTo(arr[j+1])>0){Student temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}}
}

(二)定制排序:java.util.Comparator

 

当元素的类型没有实现 java.lang.Comparable 接口而又不方便修改代码
(例如:一些第三方的类,你只有.class 文件,没有源文件)
如果一个类,实现了 Comparable 接口,也指定了两个对象的比较大小的
规则,但是此时此刻我不想按照它预定义的方法比较大小,但是我又不能
随意修改,因为会影响其他地方的使用,怎么办?
JDK 在设计类库之初,也考虑到这种情况,所以又增加了一个 java.util.Comparator 接
口。强行对多个对象进行整体排序的比较。
重写 compare(Object o1,Object o2)方法,比较 o1 和 o2 的大小:如果方法
返回正整数,则表示 o1 大于 o2;如果返回 0,表示相等;返回负整数,
表示 o1 小于 o2。
可以将 Comparator 传递给 sort 方法(如 Collections.sort 或
Arrays.sort),从而允许在排序顺序上实现精确控制。
代码:
package java.util;
public interface Comparator{int compare(Object o1,Object o2);
}

具体代码:

package com.atguigu.api;
import java.util.Comparator;
//定义定制比较器类
public class StudentScoreComparator implements Comparator {@Overridepublic int compare(Object o1, Object o2) {Student s1 = (Student) o1;Student s2 = (Student) o2;int result = s1.getScore() - s2.getScore();return result != 0 ? result : s1.getId() - s2.getId();}
}

测试类:

package com.atguigu.api;
public class TestStudent {public static void main(String[] args) {Student[] arr = new Student[5];arr[0] = new Student(3, "张三", 90, 23);arr[1] = new Student(1, "熊大", 100, 22);arr[2] = new Student(5, "王五", 75, 25);arr[3] = new Student(4, "李四", 85, 24);arr[4] = new Student(2, "熊二", 85, 18);System.out.println("所有学生:");for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}System.out.println("按照成绩排序");StudentScoreComparator sc = new StudentScoreComparator();for (int i = 1; i < arr.length; i++) {for (int j = 0; j < arr.length - i; j++) {if (sc.compare(arr[j], arr[j + 1]) > 0) {Student temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}}
}


http://www.ppmy.cn/news/60042.html

相关文章

「业务架构」波特的五力分析教程介绍

波特五力分析模型最早出现在哈佛商学院教授迈克尔E波特1979年发表在《哈佛商业评论》上的文章中。这篇论文的发表在历史上改变了企业、组织甚至国家对战略的理解。自《哈佛商业评论》创刊以来&#xff0c;它被评为十大最具影响力的论文之一。 五力分析可以帮助公司评估行业吸引…

Linux入门2(常用命令)

Linux入门2 Linux常用命令快捷键基础命令文件查看命令文件编辑命令进程管理命令用户管理命令 Linux常用命令 快捷键 Ctrl Alt T打开终端 Ctrl shift 加号 终端字体放大 ctrl 减号 终端字体缩小 基础命令 sudo su 进入管理员目录 exit 返回到用户目录 ls 当前目录下的文…

python使用aiofiles进行异步文件操作

Python是一种非常流行的编程语言&#xff0c;它在文件操作方面也有很好的支持。但是&#xff0c;当需要进行大量文件操作时&#xff0c;传统的同步方式可能会导致程序变得非常缓慢。这时&#xff0c;异步文件操作就成为了一个非常好的选择。在Python中&#xff0c;我们可以使用…

项目中遇见的问题(大文件上传,权限控制,项目管理问题,webpack打包后执行流程)

大文件上传? 前端大文件上传的思路通常是将大文件分割成多个小文件&#xff0c;然后分别上传这些小文件&#xff0c;最终在 服务器端将这些小文件重新组合成完整的大文件。以下是具体的实现思路&#xff1a; 将大文件分割成多个小文件&#xff1a;可以使用File API中的slice()…

头歌--第6关:循环语句嵌套(shell脚本入门——流程控制)

目录 任务描述 代码 任务描述 本关任务&#xff1a;掌握 shell 语句中的循环嵌套的方法和使用场景&#xff0c;输出系统中的可执行文件。 相关知识 循环语句可以在循环内使用任意类型的命令&#xff0c;包括其他循环命令。这种循环叫作嵌套循环&#xff08;nested loop&am…

初识中央处理器CPU

目录 一、CPU功能 1.控制器功能 2.运算器功能 3.功能执行顺序 4.其他功能 二、CPU结构图 1.CPU与系统总线 2.CPU内部结构 3.运算器中的寄存器组 4.控制器中的寄存器组 三、执行指令的过程 1.指令周期的基本概念 2.完整的指令周期流程 3.数据通路 4.指令周期的数据…

华为OD机试 - 打印机队列(Python)

题目描述 有5台打印机打印文件,每台打印机有自己的待打印队列。 因为打印的文件内容有轻重缓急之分,所以队列中的文件有1~10不同的代先级,其中数字越大优先级越高。 打印机会从自己的待打印队列中选择优先级最高的文件来打印。 如果存在两个优先级一样的文件,则选择最早…

Xilinx FPGA ICAP原语实现多重配置

文章目录 1. FPGA可以运行几个固件2. Xilinx ICAP原语简介3. ICAP原语模板的使用4. ICAP在Spartan-6上的使用5. ICAP在Kintex-7上的使用工程下载1. FPGA可以运行几个固件 众所周知,常见的FPGA通常为SRAM结构,固件程序一般存放在外置的串行Flash中,比如SPI Flash,M25P16或N…