目录
一.概述
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) {
//创建基本类型数组arr
int[] 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) {
//创建基本类型数组str
char[] 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) {
//创建对象数组strings
String[] 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;
}
@Override
public 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;
}
@Override
public 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, 语文=63
Process finished with exit code 0
2)为对象再专门实现一个比较器类
示例如下:
//为Grade类实现一个比较器类GradeComparator
public class GradeComparator implements Comparator<Grade> {
@Override
public int compare(Grade grade1, Grade grade2) {
//如果它们的地址相同,即指向的对象相同就返回0
if (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, 语文=63
Process 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
接口的集合
本文章到这里就结束了~