Arrays.sort()方法在Java中的使用:理论与实践
目录
一.概述
二.实现方式
三.具体介绍
1.基本数据类型数组
2.对象数组
1)使对象实现Comparable接口
2)为对象再专门实现一个比较器类
四.进阶技巧
1.基础类型数组实现自定义比较
2.如何进行逆序排序
3.lambda表达式实现比较器类
4.List的排序方法Collection.sort()
一.概述
Arrays.sort()
是Java中的一个静态方法,用于对数组进行排序。它有多个重载版本,适用于不同的数据类型和排序需求。
二.实现方式
1.对于基本数据类型数组:
- 排序算法: 快速排序算法(Quick-sort)
- 时间复杂度: O(n log n)
2.对于对象数组:
- 排序算法: 归并排序算法 (Merge-sort)
- 时间复杂度: O(n log n)
注意:归并排序具有稳定性(即相等的元素保持原有顺序)
如果对上述排序方法不熟悉,可以参考: 常见的排序方法-CSDN博客
三.具体介绍
1.基本数据类型数组
对于基本类型的数组: int[], char[], float[], double[], long[], short[] 等等,将由它们的值的大小进行升序排序
示例如下:
public class ArraysSort {public static void main(String[] args) {//创建基本类型数组arrint[] arr=new int[]{7,6,1,10,23,5};Arrays.sort(arr);//输出for(int x:arr)System.out.print(x+" ");}
}输出结果为:1 5 6 7 10 23
Process finished with exit code 0
对于字符类型同理:
public class ArraysSort {public static void main(String[] args) {//创建基本类型数组strchar[] str=new char[]{'a','v','e','o','w','b','c'};//比较的是字符的ASCII值Arrays.sort(str);//输出for(char r:str)System.out.print(r+" ");}
}结果为:a b c e o v w
Process finished with exit code 0
2.对象数组
如果想要对对象数组进行排序,则首先要保证对象是"可比较的" ,不确定它们谁大谁小怎么进行排序呢?当然JAVA库中的一些类默认实现了大小关系, 例如String类
示例如下:
public class ArraysSort {public static void main(String[] args) {//创建对象数组stringsString[] strings=new String[]{"a","banana","apple","cherry","an","pear"};//按照字典排序来确定大小关系Arrays.sort(strings);//输出for(String str:strings)System.out.print(str+" ");}
}结果为:a an apple banana cherry pear
Process finished with exit code 0
但是对于我们自己创建的类,系统就不知道如何确定它们的大小关系了,这个时候就需要我们来实现它们的"可比较性"了
想要实现对象的比较,常见的有两种方法:
- 使对象实现
Comparable
接口 - 为对象再专门实现一个比较器类
两种方法的具体介绍可以参考:Java中对象的比较方法_java 对象比较-CSDN博客
1)使对象实现Comparable
接口
示例如下:
//为创建的类实现比较接口
class Grade implements Comparable<Grade>{//姓名String name;//数学成绩int math;//英语成绩int english;//语文成绩int chinese;public Grade(String name,int math, int english, int chinese) {this.name=name;this.math = math;this.english = english;this.chinese = chinese;}//得到总成绩public int getSum(){return math+english+chinese;}@Overridepublic int compareTo(Grade grade) {//要比较的对象为null,返回大于0的值if(grade==null)return 1;//求出它们的总分int sum1=getSum();int sum2=grade.getSum();//总分不相等则返回总分之差,否则比较语文成绩if(sum1!=sum2)return sum1-sum2;else return this.chinese-grade.chinese;}@Overridepublic String toString() {return "姓名='" + name + '\'' + ", 总分=" + getSum() + ", 语文=" + chinese ;}
}public class ArraysSort {public static void main(String[] args) {//创建自定义对象Grade grade1=new Grade("小明",77,63,82);Grade grade2=new Grade("小张",89,95,88);Grade grade3=new Grade("小红",99,60,63);//创建自定义数组Grade[] grades=new Grade[]{grade1,grade2,grade3};//对于数组按照成绩进行排序Arrays.sort(grades);//输出排名,注意是升序排序,所以下标与排名相反for(int i= grades.length-1;i>=0;i--){System.out.println("第"+(grades.length-i)+"名为"+grades[i].toString());}}}结果为:第1名为姓名='小张', 总分=272, 语文=88
第2名为姓名='小明', 总分=222, 语文=82
第3名为姓名='小红', 总分=222, 语文=63Process finished with exit code 0
2)为对象再专门实现一个比较器类
示例如下:
//为Grade类实现一个比较器类GradeComparator
public class GradeComparator implements Comparator<Grade> {@Overridepublic int compare(Grade grade1, Grade grade2) {//如果它们的地址相同,即指向的对象相同就返回0if (grade1==grade2)return 0;//要比较的对象为null,直接返回if(grade1==null)return -1;//要比较的对象为null,直接返回if(grade2==null)return 1;//求出它们的总分int sum1=grade1.getSum();int sum2=grade2.getSum();//总分不相等则返回总分之差,否则比较语文成绩if(sum1==sum2)return grade1.chinese-grade2.chinese;else return sum1-sum2;}
}public class ArraysSort {public static void main(String[] args) {//创建自定义对象Grade grade1=new Grade("小明",77,63,82);Grade grade2=new Grade("小张",89,95,88);Grade grade3=new Grade("小红",99,60,63);//创建自定义数组Grade[] grades=new Grade[]{grade1,grade2,grade3};//对于数组按照成绩进行排序,注意同时传入我们实现的比较器类Arrays.sort(grades,new GradeComparator());//输出排名,注意是升序排序,所以下标与排名相反for(int i= grades.length-1;i>=0;i--){System.out.println("第"+(grades.length-i)+"名为"+grades[i].toString());}}}结果为:第1名为姓名='小张', 总分=272, 语文=88
第2名为姓名='小明', 总分=222, 语文=82
第3名为姓名='小红', 总分=222, 语文=63Process finished with exit code 0
四.进阶技巧
1.基础类型数组实现自定义比较
对于基础类型数组,Arrays.sort()默认按照它们内部的值来比较大小,本身并不支持自定义比较
但是可以将它提前包装为包装类数组,如int[]->Integer[],
然后再为Integer类实现一个比较器类就可以自定义比较了(感兴趣可以自己尝试下)
2.如何进行逆序排序
对于基础类型数组,只能等Arrays.sort()排序后,再手动逆序
对于实现了Comparable
接口的对象数组,如果不想修改接口
可以直接在排序时传入Collections.reverseOrder()参数来实现逆序排序
public static void main(String[] args) {//创建自定义对象Grade grade1=new Grade("小明",77,63,82);Grade grade2=new Grade("小张",89,95,88);Grade grade3=new Grade("小红",99,60,63);//创建自定义数组Grade[] grades=new Grade[]{grade1,grade2,grade3};//对于数组按照成绩进行排序,传入逆转参数Arrays.sort(grades, Collections.reverseOrder());//输出排名,此时就为降序输出了for(int i= 0;i<grades.length;i++){System.out.println("第"+(i+1)+"名为"+grades[i].toString());}}
3.lambda表达式实现比较器类
如果不熟悉lambda表达式,可以参考:lambda表达式-CSDN博客
在使用Arrays.sort()排序的时候,可以使用lambda表达式来直接创建一个匿名比较器内部类,
示例如下:
//创建自定义对象Grade grade1=new Grade("小明",77,63,82);Grade grade2=new Grade("小张",89,95,88);Grade grade3=new Grade("小红",99,60,63);//创建自定义数组Grade[] grades=new Grade[]{grade1,grade2,grade3};//对于数组按照成绩进行排序Arrays.sort(grades,(a,b)->{//检测a,b是否为空值if(a==null)return -1;if(b==null)return 1;//获取总分int sum1= a.getSum();int sum2= b.getSum();//总分不相等则返回总分之差,否则比较语文成绩if(sum1==sum2)return a.chinese-b.chinese;else return sum1-sum2;});
可以发现lambda表达式非常简洁的实现了比较器类
4.List的排序方法Collection.sort()
Collection.sort()
是一个静态方法,用于对实现了 List
接口的集合进行排序
本文介绍的Arrays.sort方法与Collection.sort()使用方法基本没有区别
只是一个用来排序数组,一个用来排序实现了 List
接口的集合
本文章到这里就结束了~
相关文章:

Arrays.sort()方法在Java中的使用:理论与实践
目录 一.概述 二.实现方式 三.具体介绍 1.基本数据类型数组 2.对象数组 1)使对象实现Comparable接口 2)为对象再专门实现一个比较器类 四.进阶技巧 1.基础类型数组实现自定义比较 2.如何进行逆序排序 3.lambda表达式实现比较器类 4.List的排序方法Collection.sort()…...

用AI写论文,千万不要这样用ChatGPT生成参考文献References!!
ChatGPT作为一种先进的语言大模型,被广泛用于生成文本,虽然用ChatGPT辅助论文写作已是大势所趋,但是,用于生成参考文献References的部分还是要谨慎对待。 在学术写作中,参考文献References扮演着至关重要的角色&#…...

Debian 12如何关闭防火墙
在Debian 12中,默认的防火墙管理工具是ufw(Uncomplicated Firewall)。您可以使用以下命令来关闭防火墙: 关闭防火墙: sudo ufw disable查看防火墙状态: sudo ufw status如果需要重新开启防火墙:…...

windows C++-并行编程-PPL任务并行(二)
延续任务 在异步编程中,一个异步操作在完成时调用另一个操作并将数据传递到其中的情况非常常见。 传统上,这使用回调方法来完成。 在并发运行时中,延续任务提供了同样的功能。 延续任务(也简称为“延续”)是一个异步任务,由另一个…...

快速了解 servlet(SpringMVC 的底层)
Servlet 是 Java EE(现 Jakarta EE)中用于处理 Web 请求的核心组件。它在 Web 应用程序的服务器端运行,负责接收和处理客户端(如浏览器)的请求,并生成响应。 尽管现代Web开发更多采用SpringMVC等框架&…...

QT中tr的作用是什么
在Qt框架中,tr() 函数是一个非常重要的宏,它用于国际化和本地化(i18n和l10n)支持。tr() 函数使得Qt应用程序能够根据不同的语言环境(locale)显示相应的翻译文本,从而支持多种语言。 具体来说&a…...

OpenCV结构分析与形状描述符(7)计算轮廓的面积的函数contourArea()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 计算轮廓的面积。 该函数计算轮廓的面积。与 moments 类似,面积是使用格林公式计算的。因此,返回的面积与你使用 drawCo…...

内网环境使用Docker部署Qwen2模型-vLLM篇
在此之前,我们已成功利用Docker与Ollama框架,在内网环境中部署了Qwen2模型。下面我们再来看一下使用Docker与vLLM框架部署Qwen2模型。 准备vLLM镜像 在一台具备网络环境的机器上执行以下命令,拉取vLLM的镜像: # 官方镜像 docke…...

Rust的常数、作用域与所有权
【图书介绍】《Rust编程与项目实战》-CSDN博客 《Rust编程与项目实战》(朱文伟,李建英)【摘要 书评 试读】- 京东图书 (jd.com) Rust到底值不值得学,之一 -CSDN博客 Rust到底值不值得学,之二-CSDN博客 Rust的数据类型-CSDN博客 3.7 常…...

Spring 源码解读:解决循环依赖的三种方式
引言 在复杂的应用开发中,循环依赖是一个常见的问题。简单来说,循环依赖是指两个或多个Bean之间互相依赖,导致程序无法正常实例化这些Bean。Spring容器通过依赖注入(DI)来管理Bean的创建与生命周期,并在遇…...

Web3 详解
1. 使用 Web3 库 Web3 是一个 JavaScript 库,可用于通过 RPC 通信与以太坊节点通信。 Web3 的工作方式是,公开已通过 RPC 启用的方法,这允许开发利用 Web3 库的用户界面,以便与部署在区块链上的合约进行交互。 一旦 Geth JavaScri…...

Spring 中依赖注入注解的区别详解
一、依赖注入的基本概念 依赖注入是一种设计模式,通过将对象的依赖以参数的形式传入类中,而不是在类中自行创建依赖对象。这样做有几个好处: 降低耦合度:类与类之间的依赖关系变得更清晰,避免了硬编码依赖。提高可测试性:通过依赖注入,可以轻松地进行单元测试,因为可以…...

PTA求一批整数中出现最多的个位数字
作者 徐镜春 单位 浙江大学 给定一批整数,分析每个整数的每一位数字,求出现次数最多的个位数字。例如给定3个整数1234、2345、3456,其中出现最多次数的数字是3和4,均出现了3次。 输入格式: 输入在第1行中给出正整数…...

探索国产编程工具:如何实现工作效率翻倍
在当前软件开发领域,国产编程工具正在迅速发展,它们在功能、性能以及用户体验上都有显著提升,以下是一些国产编程工具,它们可以帮助开发者提升工作效率。 智能代码编辑器 CodeGeeX:这是一款由清华大学和智谱AI合作开…...

秒懂:进程相关的操作
1.进程的查看 1.1创建test.cc文件,运行以下代码 #include <stdio.h> #include <sys/types.h> #include <unistd.h>int main() {while(1){sleep(1);} return 0;}1.2 执行以下命令 1. 运行test.cc文件 并将其最终的可执行文件命名为 test gcc t…...

PDF 软件如何帮助您编辑、转换和保护文件。
如何找到最好的 PDF 编辑器。 无论您是在为您的企业寻找更高效的 PDF 解决方案,还是尝试组织和编辑主文档,PDF 编辑器都可以在一个地方提供您需要的所有工具。市面上有很多 PDF 编辑器 — 在决定哪个最适合您时,请考虑这些因素。 1. 确定您的…...

蓝桥杯嵌入式国三备赛经验分享
1 学习STM32入门视频 向大家推荐一套宝藏级别的视频:【STM32入门教程-2023版 细致讲解 中文字幕】 如果已经比过蓝桥杯单片机或学习过单片机相关课程的同学,你们可以尝试不需要STM32套件进行学习。如果没有学过单片机相关课程的同学,可以买…...

AI编程工具合集
1. 简介 1.1. 概述 AI编程,即人工智能编程,是编写用于创建智能系统(如机器学习模型、自然语言处理应用程序等)的代码的过程。AI编程涉及使用算法和数据结构来实现能够执行任务的程序,这些任务通常需要人类智能才能完成。 AI编程的基础是计算机科学原理,包括数据结构、…...

[网络编程]通过java用TCP实现网络编程
文章目录 一. 通过java用TCP实现网络编程api介绍代码实现上述代码存在的问题 一. 通过java用TCP实现网络编程 api介绍 1. ServerSocket ServerSocket是专门给服务器用的api 构造方法: 方法: 2. Socket 不管是客⼾端还是服务端Socket,都是双⽅建⽴连接以后&#…...

Python(TensorFlow)和Java及C++受激发射损耗导图
🎯要点 神经网络监督去噪预测算法聚焦荧光团和检测模拟平台伪影消除算法性能优化方法自动化多尺度囊泡动力学成像生物研究多维分析统计物距粒子概率算法 Python和MATLAB图像降噪算法 消除噪声的一种方法是将原始图像与表示低通滤波器或平滑操作的掩模进行卷积。…...

IEEE投稿模板翻译
>将这一行替换为您的稿件id号(双击此处编辑)< IEEE 期刊和会议论文的撰写准备(2022) 第一作者 A. 作者,IEEE成员,第二作者 B. 作者,第三作者 C. 作者 Jr.,IEEE成员 摘要—本文档为IEEE会刊、期刊和…...

log4j 1.x 日志输出线程以唯一ID的形式配置
在 Log4j 1.x 中,直接以线程ID(如Java中的Thread.currentThread().getId()返回的ID)的形式记录日志是可行的,但 Log4j 1.x 本身并不直接提供一个内建的、自动将每个线程ID转换为“同一时间段内唯一ID”的机制。线程ID本身在JVM的上…...

宏观学习笔记:GDP分析(二)
GDP分析(一)主要是介绍GDP相关的定义以及核算逻辑,本节主要介绍GDP的分析思路。GDP分析主要是2种方法:总量分析和结构分析。 1. 总量分析 1.1 数值选择 一般情况下,分析的对象都是 官方公布的GDP当季值。 1.2 趋势规…...

两个月冲刺软考——访问位与修改位的题型(淘汰哪一页);内聚的类型;关于码制的知识点;地址映射的相关内容
1.访问位与修改位的题型(淘汰哪一页) 访问位:为1时表示在内存期间被访问过,为0时表示未被访问;修改位:为1时表示该页面自从被装入内存后被修改过,为0时表示未修改过。 置换页面时,最先置换访问位和修改位为…...

C高级编程 第十六天(树 二叉树)
1.树 1.1结构特点 非线性结构,有一个直接前驱,但可能有多个直接后继有递归性,树中还有树可以为空,即节点个数为零 1.2相关术语 根:即根结点,没有前驱叶子:即终端结点,没有后继森…...

OpenCV结构分析与形状描述符(11)椭圆拟合函数fitEllipse()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 围绕一组2D点拟合一个椭圆。 该函数计算出一个椭圆,该椭圆在最小二乘意义上最好地拟合一组2D点。它返回一个内切椭圆的旋转矩形。使…...

904.水果成篮
题目 链接:leetcode链接 思路分析(滑动窗口) 读完题目,很明显,这个题目需要我们寻找一个最长子数组,使得这个子数组里面最多存在两种不同的数字,很容易联想到使用滑动窗口。 另外ÿ…...

【网络安全】漏洞挖掘之 2FA 恢复代码安全措施不当
未经许可,不得转载。 文章目录 正文正文 目标:example.com 2024年6月,我在HackerOne上参与一个私人项目时发现了一个与2FA(双因素身份验证)恢复代码管理相关的安全漏洞。该漏洞发生在用户禁用并重新启用2FA的过程中。问题在于,系统在2FA重新启用后,仍然接受此前生成的…...

指令微调与参数微调的代码实践与分析
文章目录 指令微调的实验性分析LoRA 代码实践与分析指令微调的示例代码与预训练的代码高度一致,区别主要在于指令微调数据集的构建(SFTDataset)和序列到序列损失的计算(DataCollatorForSupervisedDataset)。以下代码展示了 LLMBox 和 YuLan-Chat 中指令微调的整体训练流程…...

Android14音频进阶之高通Elite架构指定通道播放(八十四)
简介: CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏: 多媒体系统工程师系列【原创干货持续更新中……】🚀 优质视频课程:AAOS车载系统+…...