当前位置: 首页 > news >正文

Java——比较器

引入的背景

我们知道基本数据类型的数据(除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 的典型实现:(默认都是从小到大排列的)

  • String:按照字符串中字符的Unicode值进行比较
  • Character:按照字符的Unicode值来进行比较
  • 数值类型对应的包装类以及BigInteger、BigDecimal:按照它们对应的数值大小进行比较
  • Boolean:true 对应的包装类实例大于 false 对应的包装类实例
  • Date、Time等:后面的日期时间比前面的日期时间大

测试String

代码示例:

 @Testpublic void test1(){//测试String已经写好的String [] a = new String[]{"Jack", "Tom", "Lucy"};//排序之前for (int i = 0; i < a.length; i++) {System.out.print(a[i]+"\t");}System.out.println();//使用Arrays进行排序Arrays.sort(a);//排序之后进行展示for (int i = 0; i < a.length; i++) {System.out.print(a[i]+"\t");}}

运行效果:

在这里插入图片描述

测试自己实现comparable接口

Product类

package cn.edu.chd.exer1;import java.util.Objects;public class Product implements Comparable{private String name;private double prices;//无参构造public Product() {}//全参构造public Product(String name, double prices) {this.name = name;this.prices = prices;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getPrices() {return prices;}public void setPrices(double prices) {this.prices = prices;}@Overridepublic String toString() {return "Product{" +"name='" + name + '\'' +", prices=" + prices +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Product product = (Product) o;return Double.compare(product.prices, prices) == 0 && name.equals(product.name);}@Overridepublic int hashCode() {return Objects.hash(name, prices);}@Overridepublic int compareTo(Object o) {//如果是同一个对象,return 0if (this == o){return 0;}//两个对象比较的标准是:价格从小到大,价格一样的话,按照名字从小到大if (o instanceof Product){Product p = (Product)o;int v = Double.compare(this.prices, p.prices);
//            return v;if (v != 0){return v;}//价格如果相同,名字按照从小到大return this.name.compareTo(p.name);}//手动抛异常throw new RuntimeException("类型不匹配");}
}

测试

    //对不同对象的大小进行排序@Testpublic void test2(){//商品数组Product[] products = new Product[5];//全参构造器,在new对象时就对属性进行赋值products[0] = new Product("Huawei", 5999);products[1] = new Product("XiaoMi", 4999);products[2] = new Product("iPhone", 9999);products[3] = new Product("vivo", 3999);products[4] = new Product("Honer", 5999);System.out.println("排序之前");//排序之前的遍历for (int i = 0; i < products.length; i++) {System.out.println(products[i]);}System.out.println("----------------------------------------------");//使用arrays进行排序Arrays.sort(products);System.out.println("排序之后");//排序后的遍历for (int i = 0; i < products.length; i++) {System.out.println(products[i]);}}

运行效果

在这里插入图片描述

定制排序:java.util.Comparator

思考

  • 当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码(例如:一些第三方的类,你只有.class文件,没有源文件)
  • 如果一个类,实现了Comparable接口,也指定了两个对象的比较大小的规则,但是此时此刻我不想按照它预定义的方法比较大小,但是我又不能随意修改,因为会影响其他地方的使用,怎么办?(例如:我想要String按照字母从大到小的顺序排序,而不是默认的从小到大)

JDK在设计类库之初,也考虑到这种情况,所以又增加了一个java.util.Comparator接口。强行对多个对象进行整体排序的比较。

  • 重写compare(Object o1,Object o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2。
  • 可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制。

Product类

package cn.edu.chd.exer2;import java.util.Objects;public class Product implements Comparable{private String name;private double prices;//无参构造public Product() {}//全参构造public Product(String name, double prices) {this.name = name;this.prices = prices;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getPrices() {return prices;}public void setPrices(double prices) {this.prices = prices;}@Overridepublic String toString() {return "Product{" +"name='" + name + '\'' +", prices=" + prices +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Product product = (Product) o;return Double.compare(product.prices, prices) == 0 && name.equals(product.name);}@Overridepublic int hashCode() {return Objects.hash(name, prices);}@Overridepublic int compareTo(Object o) {//如果是同一个对象,return 0if (this == o){return 0;}//两个对象比较的标准是:价格从小到大,价格一样的话,按照名字从小到大if (o instanceof Product){Product p = (Product)o;int v = Double.compare(this.prices, p.prices);
//            return v;if (v != 0){return v;}//价格如果相同,名字按照从小到大return this.name.compareTo(p.name);}//手动抛异常throw new RuntimeException("类型不匹配");}
}

按照商品的价格从低到高排序的comparator

 @Testpublic void test1(){//new一个comparator接口的匿名实现类Comparator comparator = new Comparator() {//按照商品的价格从低到高排序@Overridepublic int compare(Object o1, Object o2) {if (o1 == o2){return 0;}if (o1 instanceof Product && o2 instanceof Product){//强转Product p1 = (Product) o1;Product p2 = (Product) o2;return Double.compare(p1.getPrices(), p2.getPrices());}throw new RuntimeException("类型不匹配");}};//商品数组Product[] products = new Product[5];//全参构造器,在new对象时就对属性进行赋值products[0] = new Product("Huawei", 5999);products[1] = new Product("XiaoMi", 4999);products[2] = new Product("iPhone", 9999);products[3] = new Product("vivo", 3999);products[4] = new Product("Honer", 5999);System.out.println("排序之前");//排序之前的遍历for (int i = 0; i < products.length; i++) {System.out.println(products[i]);}System.out.println("----------------------------------------------");//将comparator对象作为参数进行传入,排序Arrays.sort(products, comparator);System.out.println("排序之后");//排序后的遍历for (int i = 0; i < products.length; i++) {System.out.println(products[i]);}}

运行效果:

在这里插入图片描述

按照名称进行排序的comparator

   //按照名称进行排序@Testpublic void test2(){//new一个comparator接口的匿名实现类Comparator comparator = new Comparator() {//按照商品的名称进行排序@Overridepublic int compare(Object o1, Object o2) {if (o1 == o2){return 0;}if (o1 instanceof Product && o2 instanceof Product){//强转Product p1 = (Product) o1;Product p2 = (Product) o2;return p1.getName().compareTo(p2.getName());}throw new RuntimeException("类型不匹配");}};//商品数组Product[] products = new Product[5];//全参构造器,在new对象时就对属性进行赋值products[0] = new Product("Huawei", 5999);products[1] = new Product("XiaoMi", 4999);products[2] = new Product("iPhone", 9999);products[3] = new Product("vivo", 3999);products[4] = new Product("Honer", 5999);System.out.println("排序之前");//排序之前的遍历for (int i = 0; i < products.length; i++) {System.out.println(products[i]);}System.out.println("----------------------------------------------");//将comparator对象作为参数进行传入,排序Arrays.sort(products, comparator);System.out.println("排序之后");//排序后的遍历for (int i = 0; i < products.length; i++) {System.out.println(products[i]);}}

运行效果:

在这里插入图片描述

http://www.lryc.cn/news/164880.html

相关文章:

  • 【数据结构】初识泛型
  • 代码随想录--哈希--有效的字母异位词
  • MySQL——数据的增删改
  • 云服务器与http服务器
  • golang教程 beego框架笔记一
  • 【深度学习】Mini-Batch梯度下降法
  • AI项目六:WEB端部署YOLOv5
  • 敲代码常用快捷键
  • MyBatis: 分页插件PageHelper直接传递分页参数的用法
  • Python基于Flask的高校舆情分析,舆情监控可视化系统
  • Python第一次作业练习
  • InstallShield打包升级时不覆盖原有文件的解决方案
  • 服务器巡检表-监控指标
  • 无涯教程-JavaScript - DDB函数
  • uniapp打包微信小程序。报错:https://api.weixin.qq.com 不在以下 request 合法域名列表
  • stm32之31.iic
  • 新的 ChatGPT 提示工程技术:程序模拟
  • 【Python】爬虫基础
  • leetcode分类刷题:队列(Queue)(三、优先队列用于归并排序)
  • 无线窨井水位监测仪|排水管网智慧窨井液位计安装案例
  • 024 - STM32学习笔记 - 液晶屏控制(一) - LTDC与DMA2D初始
  • Python数据容器:dict(字典、映射)
  • 2023年基因编辑行业研究报告
  • Spring MVC:请求转发与请求重定向
  • 按键灯待机2秒后灭掉
  • SpringBoot通过自定义注解实现日志打印
  • 代码随想录算法训练营第七天 |151.翻转字符串里的单词
  • 【WebRTC---源码篇】(十:一)WEBRTC 发送视频RTP包
  • cmd 90 validate error!(达梦数据库日志报错)
  • Shape Completion Enabled Robotic Grasping