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

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 接口的集合


本文章到这里就结束了~

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

相关文章:

  • 用AI写论文,千万不要这样用ChatGPT生成参考文献References!!
  • Debian 12如何关闭防火墙
  • windows C++-并行编程-PPL任务并行(二)
  • 快速了解 servlet(SpringMVC 的底层)
  • QT中tr的作用是什么
  • OpenCV结构分析与形状描述符(7)计算轮廓的面积的函数contourArea()的使用
  • 内网环境使用Docker部署Qwen2模型-vLLM篇
  • Rust的常数、作用域与所有权
  • Spring 源码解读:解决循环依赖的三种方式
  • Web3 详解
  • Spring 中依赖注入注解的区别详解
  • PTA求一批整数中出现最多的个位数字
  • 探索国产编程工具:如何实现工作效率翻倍
  • 秒懂:进程相关的操作
  • PDF 软件如何帮助您编辑、转换和保护文件。
  • 蓝桥杯嵌入式国三备赛经验分享
  • AI编程工具合集
  • [网络编程]通过java用TCP实现网络编程
  • Python(TensorFlow)和Java及C++受激发射损耗导图
  • IEEE投稿模板翻译
  • log4j 1.x 日志输出线程以唯一ID的形式配置
  • 宏观学习笔记:GDP分析(二)
  • 两个月冲刺软考——访问位与修改位的题型(淘汰哪一页);内聚的类型;关于码制的知识点;地址映射的相关内容
  • C高级编程 第十六天(树 二叉树)
  • OpenCV结构分析与形状描述符(11)椭圆拟合函数fitEllipse()的使用
  • 904.水果成篮
  • 【网络安全】漏洞挖掘之 2FA 恢复代码安全措施不当
  • 指令微调与参数微调的代码实践与分析
  • Android14音频进阶之高通Elite架构指定通道播放(八十四)
  • 常见的正则化方法以及L1,L2正则化的简单描述