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

JAVA 中的比较器

先看一个示例:

public class Person {private String name;private int age;public Person(String name,int age){this.name = name;this.age = age;}/*** 重写 toString 方法* @return*/@Overridepublic String toString() {return "["+this.name + "," + this.age + "]";}
}
import java.util.Arrays;public class Test {public static void main(String[] args) {//声明定义一个元素类型为 Person 类型的数组Person[] persons = {new Person("张三",  22),new Person("李四", 11),new Person("王五", 33)};//先输出排序前的数组System.out.println(Arrays.toString(persons));//对数组进行排序Arrays.sort(persons);//输出排序后的数组System.out.println(Arrays.toString(persons));}
}

 打印结果:

        报 java.lang.ClassCastException 异常,即 Person 类型的实例对象不能向上转型转换成 Comparable 接口类型进行比较,原因是 Person 类并没有实现 Comparable 接口。

在排序的过程中为什么要把 Person 类型的实例对象向上转型转 Comparable 接口类型?

        因为如果直接对 Person 类型的实例对象进行大小比较是没有比较的依据,我们需要对 Person 类型的实例对象大小比较制定规则,需要让 Person 类实现 Comparable 接口并重写接口中的 compareTo() 方法,即对接口中重写的 compare() 方法就是用来指定比较 Person 类型的实例对象大小的规则的。

Comparable 接口

        一个类实现了 Comparable 接口就表示该类在定义的时候就得重写 Comparable 接口中的 compareTo() 方法,指定比较该类类型实例对象比较大小的规则。

Comparable 接口源码:

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

        在 Comparable 接口中只有一个 compareTo(T o) 方法,此方法的返回值是 int 类型的整数,因此我们在重写该方法的时候是通过返回的 int 类型的整数来判断两个对象的大小的。

(1)> 0 如果方法的调用对象 - 参数对象,返回值为正整数,即表示调用对象大于参数对象;

(2)< 0 如果方法的调用对象 - 参数对象,返回值为负整数,即表示调用对象小于参数对象;

(3)== 0 如果方法的调用对象 - 参数对象,返回值为 0,即表示调用对象等于参数对象;

所以要对上面的 Person 类进行修改,实现 Comparable 接口,并重写 compareTo 方法。

示例:

public class Person implements Comparable<Person>{private String name;private int age;public Person(String name,int age){this.name = name;this.age = age;}/*** 重写 toString 方法* @return*/@Overridepublic String toString() {return "["+this.name + "," + this.age + "]";}/*** 重写比较器的方法,用年龄排序* @param o the object to be compared.* @return*/@Overridepublic int compareTo(Person o) {if(this.age > o.age) {return 1;}if(this.age < o.age) {return -1;}return 0;}
}

再进行比较:

import java.util.Arrays;public class Test {public static void main(String[] args) {//声明定义一个元素类型为 Person 类型的数组Person[] persons = {new Person("张三",  22),new Person("李四", 11),new Person("王五", 33)};//先输出排序前的数组System.out.println(Arrays.toString(persons));//对数组进行排序Arrays.sort(persons);//输出排序后的数组System.out.println(Arrays.toString(persons));}
}

打印结果:

        此时就可以完成 Person 类型实例对象的大小关系比较,具体依据的是 Person 类型实例对象的 age 的大小。

Comparator 接口

        Comparator 接口被称之为可挽救的比较器,如果一个类在定义的时候并没有实现 Comparable 接口,也就表示无法比较该类类型的实例对象的大小,但是现在确实需要比较该类类型的实例对象的大小,由于类已经声明定义好了,无法修改了,只能考虑在不修改源类的基础上,也能够制定较该类类型的实例对象的大小规则,此时就可以用可挽救的比较器 Comparator 接口。

Comparator 接口部分源码:

@FunctionalInterface
public interface Comparator<T> {int compare(T o1, T o2);//省略部分...
}

        在 Comparator 接口中同样有一个用来比较两个对象大小关系的 compare(T o1, T o2) 方法,同样使用 int 类型的返回值来表示参与比较的两个对象的大小关系。

(1)> 0 如果返回值为正整数,即表示对象 o1 大于 o2;

(2)< 0 如果返回值为正整数,即表示对象 o1 小于 o2;

(3)== 0 如果返回值为 0,即表示对象 o1 等于 o2;

没有实现 Comparable 接口的情况:

public class Person{private String name;private int age;public Person(String name,int age){this.name = name;this.age = age;}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;}/*** 重写 toString 方法* @return*/@Overridepublic String toString() {return "["+this.name + "," + this.age + "]";}
}

  这样依旧可以进行比较:

import java.util.Arrays;
import java.util.Comparator;public class Test {public static void main(String[] args) {//声明定义一个元素类型为 Person 类型的数组Person[] persons = {new Person("张三",  22),new Person("李四", 11),new Person("王五", 33)};//先输出排序前的数组System.out.println(Arrays.toString(persons));//对数组进行排序Arrays.sort(persons, new Comparator<Person>() {// 重写 compare 方法@Overridepublic int compare(Person o1, Person o2) {if(o1.getAge() < o2.getAge()) {return -1;}if(o1.getAge() > o2.getAge()) {return 1;}return 0;}});//输出排序后的数组System.out.println(Arrays.toString(persons));}
}

打印结果:


http://www.mrgr.cn/news/51308.html

相关文章:

  • 软件测试学习笔记丨接口自动化测试-接口请求
  • spring/springboot获取resource目录下的文件
  • RAG中向量召回怎么做
  • 一个基于vue功能强大的表格组件--vxe-table的二次封装
  • Ascend C算子编程和C++基础 Lesson3-4 性能优化
  • spring boot 3.3.4 网关(gateway) 集成knife4j 4.4.0
  • FreeRTOS:消息队列
  • PyTorch搭建GNN(GCN、GraphSAGE和GAT)实现多节点、单节点内多变量输入多变量输出时空预测
  • C++面向对象之多态
  • UI自动化测试 —— web端元素获取元素等待实践!
  • 数据库管理工程师证书,是“敲门砖”还是“鸡肋”?
  • 如何开启华为交换机 http
  • windows中 GDTR和GDT关于快速调用的实现1
  • 生信软件38 - 基因型填充软件IMPUTE2
  • 重磅优惠,节省高达56%
  • Spring专题
  • misc-stuff: jump into thinking
  • 【Python机器学习】入门机器学习算法,打造智能应用!
  • 河源市社保卡照片要求及手机自拍拿数码相片回执的方法
  • 代码随想录算法训练营第三十五天|452. 用最少数量的箭引爆气球,435. 无重叠区间,763. 划分字母区间