排序 Comparable接口、Comparator接口
String类的Comparable接口
1、String类实现了Comparable<String>接口,并提供了compareTo方法的实现,因此,字符串对象(即String类型的实例)可以直接调用compareTo()方法来比较它们。2、String类的compareTo()方法是这样工作的:它按照字典顺序比较两个字符串,从两个字符串的第一个字符开始比较,如果它们相等,则继续比较下一个字符,直到找到不同的字符或者到达字符串的末尾,如果所有的字符都相同,那么较短的字符串被认为是较小的。
排序
Comparable接口
"实现Comparable接口 ,就必须重写它的compareTo()方法""Comparable接口"是一个泛型接口,在类的声明中使用泛型参数,来指定需要比较的对象类型,它包含一个compareTo()方法,如下所示:public interface Comparable<T> {int compareTo(T o);}"compareTo()方法",返回一个整数值,用于表示当前对象,与另一个对象的比较结果。通常,它有以下三种返回值:如果,当前对象 小于 另一个对象,则返回,负整数。如果,当前对象 等于 另一个对象,则返回,零。如果,当前对象 大于 另一个对象,则返回,正整数。使用的场景:1、具体的类A,实现Comparable接口2、重写Comparable接口中的compareTo(Object obj)方法,在此方法中指明比较类A的对象的大小的标准3、创建类A的多个实例,进行大小的比较或排序。
实现Comparable接口
要使一个类可以进行自然排序,需要实现"Comparable接口"并提供"compareTo()方法的具体实现",在compareTo()方法中,你需要指定对象之间的比较规则,如:
"Student.java"
public class Student implements Comparable<Student> {private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic int compareTo (Student other){return this.age - other.age;}public String toString() {return "Student{name='" + name + "', age=" + age + '}';}
}
Student类实现了Comparable<Student>接口,并重写了compareTo()方法,按照年龄升序排序,是通过比较当前对象的年龄属性和另一个对象的年龄属性来实现的。"MyTest.java"
import java.util.TreeSet;
public class MyTest {public static void main(String[] args) {TreeSet<Student> studentSet = new TreeSet<>();studentSet.add(new Student("Alice", 22));studentSet.add(new Student("Bob", 20));studentSet.add(new Student("Charlie", 25));for (Student student : studentSet) {System.out.println(student);}}
}
/* 打印结果如下:Student{name='Bob', age=20}Student{name='Alice', age=22}Student{name='Charlie', age=25}
*/"对上面的代码做一下解释"在Java中,当你创建一个实现了Comparable接口的类的实例,并将其放入一个TreeSet集合时,TreeSet会自动使用该类实现的compareTo()方法来对集合中的元素进行排序,你不需要显式地调用compareTo()方法,因为,TreeSet内部在需要时会自动调用它。另:1、创建TreeSet实例:当你创建 "TreeSet<Student> studentSet" 时,实际上是在告诉Java你想要一个有序的、不重复的集合,该集合将包含Student类型的对象。2、添加元素到TreeSet:当你调用 "studentSet.add(new Student("Alice", 22))" 等方法添加元素时,TreeSet内部会检查新元素与集合中已存在元素的顺序关系,这是通过调用新元素的compareTo方法实现的。3、自动排序:在TreeSet内部,元素是以红黑树的结构存储的,当你添加一个新元素时,TreeSet会使用compareTo()方法来确定新元素在树中的正确位置,以保持集合的有序性,这个过程是自动的,你不需要显式地调用任何排序方法。4、遍历TreeSet:当你遍历TreeSet时(使用for-each循环),你会看到元素已经按照compareTo方法定义的顺序排列好了。这个例子中,Student类实现了Comparable<Student>接口,并重写了compareTo方法,该方法比较两个Student对象的age属性,因此,当你将Student对象添加到TreeSet时,它们会按照年龄升序排列。
Collections.sort
"Student.java"
public class Student implements Comparable<Student>{private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic int compareTo(Student other) {return this.age - other.age;}public String toString() {return "Student{name='" + name + "', age=" + age + '}';}
}import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Test1 {public static void main(String[] args) {List<Student> list = new ArrayList<>();list.add(new Student("Alice", 22));list.add(new Student("White", 18));list.add(new Student("Black", 30));// 使用了Collections.sort()方法,对学生列表进行了排序Collections.sort(list);for (Student stu : list){System.out.println(stu);}/*打印结果为:Student{name='White', age=18}Student{name='Alice', age=22}Student{name='Black', age=30}* 使用了Collections.sort()方法,对学生列表进行了排序,* 因为,Student类实现了 Comparable 接口,* 所以,它根据年龄属性自动进行了升序排序。* */}
}为什么 Collections.sort(list) 会使用 Student类的compareTo()方法进行排序呢?因为,Student类实现了Comparable<Student>接口并重写了compareTo()方法,所以,当你调用 Collections.sort(list)时,该方法会自动调用,Student类中的compareTo()方法,来比较对象并进行排序。
自定义排序
"要求"有时,需要对对象进行多属性排序,例如,先按年龄升序排序,然后按姓名字母顺序排序,为了实现多属性排序,可以在 compareTo()方法中逐一比较不同属性,确保按照所需顺序比较。"Person.java"
public class Person implements Comparable<Person>{String name;int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic int compareTo(Person other) {// 先按年龄升序int ageComparison = this.age - other.age;if (ageComparison != 0) {return ageComparison;}// 如果年龄相等,则按照名字字母排序return this.name.compareTo(other.name);}@Overridepublic String toString() {return "Student{name='" + name + "', age=" + age + '}';}
}import java.util.Collections;
import java.util.List;
public class PersonTest {public static void main(String[] args) {List<Person> list = new ArrayList<>();list.add(new Person("Wang", 26));list.add(new Person("King", 19));list.add(new Person("He", 19));list.add(new Person("Black", 28));/*为了对列表进行排序,需要调用Collections.sort()方法,并传递您的Person列表作为参数,因为,Person类实现了Comparable<Person>接口,并定义了比较逻辑,所以,Collections.sort()方法将能够使用Person类中的compareTo()方法来对列表进行排序。*/Collections.sort(list);for (Person per : list) {System.out.println(per);}/** 打印结果为:Student{name='He', age=19}Student{name='King', age=19}Student{name='Wang', age=26}Student{name='Black', age=28}* */}
}
Comparator定制排序
什么时候使用?当,元素的类型没有实现java.lang.Comparable接口,而又不方便修改代码(比如JDK当中的类),或者,实现了java.lang.Comparable接口,但定义好的排序规则不适合当前的操作,那么,可以考虑使用接口Comparator的对象来排序,强行对多个对象进行整体排序的比较。1、public interface Comparator<T>Comparator属于接口且支持范型,位于java.util包下2、Comparator接口,内置实现自定义排序的抽象方法compare(),int compare(T o1,T o2),T:泛型,这个方法是让两个形参对象去比较大小。重写compare(Object o1,Object o2)方法,比较o1和o2的大小:如果,返回,正整数,则表示o1大于o2如果,返回0,表示相等如果,返回负整数,表示 o1小于o2需要在compare中指明o1和o2按照什么规则比较3、可以将Comparator传递给sort方法(如 Collections.sort或Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用 Comparator 来控制某些数据结构(如有序set 或 有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。
Arrays类下的sort方法
public static <T> void sort(T[] a, Comparator<? super T> c)
对基本数据类型的排序
import java.util.Arrays;
import java.util.Comparator;public class TestComparator {public static void main(String[] args) {Integer[] arr1 = {1,4,2,3};// 降序Arrays.sort(arr1, new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o2 - o1;}});System.out.println(Arrays.toString(arr1)); // [4, 3, 2, 1]// 升序Arrays.sort(arr1, new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o1 - o2;}});System.out.println(Arrays.toString(arr1)); // [1, 2, 3, 4]}
}
对象数组的排序
"StuComparator.java"
public class StuComparator {String name;int age;double height;public StuComparator() {}public StuComparator(String name, int age, double height) {this.name = name;this.age = age;this.height = height;}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 double getHeight() {return height;}public void setHeight(double height) {this.height = height;}@Overridepublic String toString() {return "\n" + "name=" + name + ", age=" + age + ", height=" + height + " \n";}
}"TestStuComparator.java"
import java.util.Arrays;
import java.util.Comparator;
public class TestStuComparator {public static void main(String[] args) {StuComparator[] stu = new StuComparator[4];stu[0] = new StuComparator("张三", 16, 176.6);stu[1] = new StuComparator("李四", 25, 181.3);stu[2] = new StuComparator("小明", 18, 179.4);stu[3] = new StuComparator("小红", 17, 165);// 以年龄排序Arrays.sort(stu, new Comparator<StuComparator>() {@Overridepublic int compare(StuComparator o1, StuComparator o2) {return o1.age - o2.age;}});System.out.println(Arrays.toString(stu));/*[name=张三, age=16, height=176.6,name=小红, age=17, height=165.0,name=小明, age=18, height=179.4,name=李四, age=25, height=181.3]*/// 以身高排序Arrays.sort(stu, new Comparator<StuComparator>() {@Overridepublic int compare(StuComparator o1, StuComparator o2) {return Double.compare(o1.height, o2.height);}});System.out.println(Arrays.toString(stu));/*[name=小红, age=17, height=165.0,name=张三, age=16, height=176.6,name=小明, age=18, height=179.4,name=李四, age=25, height=181.3]*/}
}
相关文章:
排序 Comparable接口、Comparator接口
String类的Comparable接口 1、String类实现了Comparable<String>接口,并提供了compareTo方法的实现,因此,字符串对象(即String类型的实例)可以直接调用compareTo()方法来比较它们。2、String类的compareTo()方法…...

得帆助力大族激光主数据平台建设,用数据为企业生产力赋能
本期客户 大族激光科技产业集团股份有限公司(以下简称“大族激光”)是一家从事工业激光加工设备与自动化等配套设备及其关键器件的研发、生产、销售,激光、机器人及自动化技术在智能制造领域的系统解决方案的优质提供商,是国内激光…...

实名认证电子签署:防范合同纠纷,提升交易信任
当今社会,随着数字化和信息化的发展,电子合同已经成为商务活动中常见的签署方式。而在签署电子合同时进行实名认证,是为了确保合同的真实性、合法性和安全性。本文将从法律、技术和实际应用等方面详细解释为什么签署电子合同需要进行实名认证…...
c++ primer中文版第五版作业第十八章
仓库地址 文章目录 18.118.218.318.418.518.618.718.818.918.1018.1118.1218.1318.1418.1518.16位置一using声明 位置二using声明 位置一using指示 位置二using指示 18.1718.1818.1918.2018.2118.2218.2318.2418.2518.2618.2618.2818.2918.30 18.1 此时r是一个range_error类型…...
vue触发真实的点击 事件 跟用户行为一致
<template><div><button ref"myButton" click"handleClick">按钮</button></div> </template><script> export default {methods: {handleClick() {const button this.$refs.myButton;// 创建一个鼠标点击事件…...

Java进程CPU高负载排查
Java进程CPU高负载排查步骤_java进程cpu使用率高排查_YouluBank的博客-CSDN博客 【问题定位】使用arthas定位CPU高的问题_arthas cpu高_秋装什么的博客-CSDN博客 CPU飙升可能原因 CPU 上下文切换过多。 对于 CPU 来说,同一时刻下每个 CPU 核心只能运行-个线程&…...
Linux编程4.1 网络编程-前导
1、内容概述 网络的基本概念TCP/IP协议概述OSI和TCP/IP模型掌握TCP协议网络基础编程掌握UDP协议网络基础檹网络高级编程 2、计算机联网的目的 使用远程资源共享信息、程序和数据分布处理 3、基本概念 单服务与多客户端的进程间通信C/S client server 由于,跨计…...

【微信小程序】传参存储
目录 一、本地数据存储 wx.setStorage wx.setStorageSync 1.1、异步缓存 存取数据 1.2、同步缓存 存取数据 二、使用url跳转路径携带参数 2.1、 wx.redirectTo({}) 2.2、 wx.navigateTo({}) 2.3、 wx.switchTab({}) 2.4 、wx.reLaunch({}) 2.5、组件跳转 三、…...

计算机设计大赛 深度学习花卉识别 - python 机器视觉 opencv
文章目录 0 前言1 项目背景2 花卉识别的基本原理3 算法实现3.1 预处理3.2 特征提取和选择3.3 分类器设计和决策3.4 卷积神经网络基本原理 4 算法实现4.1 花卉图像数据4.2 模块组成 5 项目执行结果6 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 &a…...

ping多个IP的工具
Ping Tool 项目地址 python开发的IP搜索小工具 ping一个网段所有IP,显示结果查看某个ip地址开放监听的端口配置可保存...
Rust 的 Error 如何使用?
在 Rust 中,错误处理是一个重要且核心的概念。Rust 提供了一种强大的类型系统,允许你明确地处理可能出现的错误。std::error::Error trait 是 Rust 标准库中用于表示错误的基础 trait。实现这个 trait 的类型可以被用作错误类型,并且可以使用…...

Hack The Box-Crafty
目录 信息收集 rustscan whatweb WEB 漏洞利用 漏洞说明 漏洞验证 提权 get user.txt get Administrator 总结 信息收集 rustscan ┌──(root㉿ru)-[~/kali/hackthebox] └─# rustscan -a 10.10.11.249 --range0-65535 --ulimit5000 -- -A -sC [~] Automatically…...

高电平复位电路工作原理详解
单片机复位电路的作用是:使单片机恢复到起始状态,让单片机的程序从头开始执行,运行时钟处于稳定状态、各种寄存器、端口处于初始化状态等等。目的是让单片机能够稳定、正确的从头开始执行程序。一共分为:高电平复位,低…...
了AI而强行AI的做法,构成了人与AI对抗的宿命论
从 ChatGPT到文生图的 Stable Diffusion,再到文生视频的 Sora ,每次大语言模型的迭代,以及由此衍生的新产品,都让各行各业的企业主、从业者们,感到无所适从。 普通人可以借助AI的力量“逆天改命”吗? 10多…...

【性能测试】Jmeter+InfluxDB+Grafana 搭建性能监控平台
一、背景 为什么要搭建性能监控平台? 在用 Jmeter 获取性能测试结果的时候,Jmeter自带的测试报告如下: 这个报告有几个很明显的缺点: 只能自己看,无法实时共享;报告信息的展示比较简陋单一,不…...

【YOLOv8模型网络结构图理解】
YOLOv8模型网络结构图理解 1 YOLOv8的yaml配置文件2 YOLOv8网络结构2.1 Conv2.2 C3与C2f2.3 SPPF2.4 Upsample2.5 Detect层 1 YOLOv8的yaml配置文件 YOLOv8的配置文件定义了模型的关键参数和结构,包括类别数、模型尺寸、骨干(backbone)和头部…...

付强:基于注意力机制的听觉前端处理 | 嘉宾公布
一、智能家居与会议系统专题论坛 智能家居与会议系统专题论坛将于3月28日同期举办! 智能会议系统它通过先进的技术手段,提高了会议效率,降低了沟通成本,提升了参会者的会议体验。对于现代企业、政府机构和学术界是不可或缺的。在这…...

C++_包装器
目录 1、包装器的用法 2、包装器的类型 3、包装器的作用 4、包装成员函数 5、bind(绑定) 5.1 bind的用法 5.2 bind减少参数个数 结语 前言: C11的包装器,总称为function包装器,而包装器又称适配器…...

3588板子部署yoloV5
一 :准备 ubuntu linux X86_64系统 a.安装anaconda b.创建虚拟环境 python3.8 二: 下载rknn-toolkit2 传送门 unzip 解压文件夹 三:pt转onnx模型 四:onnx转rknn模型 a:cd到rknn-toolkit2-master/rknn-toolkit2/packag…...
解决GitHub提交时不显示自己的头像 显示另一个账号(其实也是自己)
git show 看看是否是自己的githup 账号的邮箱 如果不是进行下列操作 git config user.email “你的邮箱地址”,修改邮箱 修改完以后输入git config user.email 检查是否修改成了你的邮箱 如果你想其他项目提交时,也避免此类情况,把上面的两条命令改成 (1&#…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...

Linux部署私有文件管理系统MinIO
最近需要用到一个文件管理服务,但是又不想花钱,所以就想着自己搭建一个,刚好我们用的一个开源框架已经集成了MinIO,所以就选了这个 我这边对文件服务性能要求不是太高,单机版就可以 安装非常简单,几个命令就…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
Pydantic + Function Calling的结合
1、Pydantic Pydantic 是一个 Python 库,用于数据验证和设置管理,通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发(如 FastAPI)、配置管理和数据解析,核心功能包括: 数据验证:通过…...
JS红宝书笔记 - 3.3 变量
要定义变量,可以使用var操作符,后跟变量名 ES实现变量初始化,因此可以同时定义变量并设置它的值 使用var操作符定义的变量会成为包含它的函数的局部变量。 在函数内定义变量时省略var操作符,可以创建一个全局变量 如果需要定义…...