Java 中数组的排序(基本类型,对象类型)

前言: 本文主要针对的是 Java 自带的排序函数/接口

1. Java 中数组的自定义排序方法

实现 Comparable 接口中的 compareTo 函数或实现 Comparator 接口中的 compare 函数

两者存在使用上的区别,大体而言,Comparable 接口是为类服务,Comparator 接口是为 sort (Arrays.sort / Collections.sort)方法服务

1.1 基本类型

基本类型存在很多种,这里举例 int 型数组

1.1.1 升序排列

例如想要升序排序 int 型数组 nums,可以通过调用 Arrays.sort(nums) 方法进行升序排列

int[] nums = new int[]{4, 1, 6, 3};

// 升序
Arrays.sort(nums);

具体来讲,Arrays 类中的 sort 方法这样写道

Sorts the specified array of objects into ascending order, according to the natural ordering of its elements.
解释: 根据指定数组元素的自然顺序将指定数组的对象(数组中的元素)递增排序

那么对于整数而言,就是按照升序排列

1.1.2 降序排列

那么如果我想降序排列呢?那么这种额外的“需求”就需要自定义一个比较器(Comparator),在定义完比较器后,可以由 Arrays.sort 重载函数实现这种额外的“需求”,下面是 Arrays.sort 重载函数

public static <T> void sort(T[] a, Comparator<? super T> c) {
	// ....
}

下面这段话是关于这个函数的解释

Sorts the specified array of objects according to the order induced by the specified comparator
解释: 排序的顺序是通过指定的比较器(comparator)来推断出来的,以此将数组的对象(数组中的元素)进行排序

也就是说,这个函数要求我们自定义一个比较器(Comparator),通过引入 Comparator 接口,实现这个接口中的 compare 方法来告诉 Arrays.sort 函数如何排序

除此之外,我还应注意到,这个函数使用了泛型 T,因为泛型要求包容的必须是对象类型,而 int 是基本类型,所以第一个参数 T[] a 中的 a 不能是基本类型 int[]

好在 Java 中存在基本类型的包装类,例如: int 基本类型对应着 Integer 包装类,那么我们就通过如下方式,实现 int 型数组的降序排列

int[] nums = new int[]{4, 1, 6, 3};

// 降序
Integer[] newNums = new Integer[nums.length];
for (int i = 0; i < nums.length; i++) newNums[i] = nums[i];

Arrays.sort(newNums, new Comparator<>(){
    @Override
    public int compare(Integer o1, Integer o2) {
        if (o1 > o2) return -1;// 若此处指定为1, 则为升序
        else if (o1 < o2) return 1;// 若此处指定为-1, 则为升序
        else return 0;
    }
});

关于为什么 compare 中 o1 > o2 时要返回 -1 是降序,我查询了诸多资料都得不到一个确切的解释。但是可以明确的是: 排序的顺序是基于返回值的

在升序情况下,对于 compare(Integer o1, Integer o2) 函数

if (o1 > o2) return 1;	// 或其他正整数
else if (o1 < o2) return -1;	// 或其他负整数
else return 0;	// 两者相等时

在降序情况下,对于 compare(Integer o1, Integer o2) 函数

if (o1 > o2) return -1;	// 或其他负整数
else if (o1 < o2) return 1;	// 或其他负整数
else return 0;	// 两者相等时

对于 compareTo(Integer o2) 函数也有

o1.compareTo(o2);	// 升序
-o1.compareTo(o2);	// 降序

由于 Java 8 引入的 Lambda 表达式,Arrays.sort 可以简化为

Arrays.sort(newNums, (Integer o1, Integer o2) -> {
        if (o1 > o2) return -1;
        else if (o1 < o2) return 1;
        else return 0;
});

// 我们还可以省略掉参数的类型
Arrays.sort(newNums, (o1, o2) -> {
        if (o1 > o2) return -1;
        else if (o1 < o2) return 1;
        else return 0;
});

// 当然,我们还可以直接调用 Integer 包装类中实现的 compareTo 方法(默认是升序)
// 所需要在 o1.compareTo(o2) 前加负号
Arrays.sort(newNums, (o1, o2) -> -o1.compareTo(o2));

// 此外,我们还可以调用 Collections 类中的 reverseOrder 方法来实现逆序
Arrays.sort(newNums, Collections.reverseOrder());

至此,我们可以完成基本类型的降序排序

1.2 对象(自定义)类型

对象类型存在很多种,这里举例 String 型数组

1.2.1 实现 Comparable 接口中的 compareTo 函数

// Comparable 接口一般由自定类所实现,例如有 Person 类,想以 age 升序排序 Person 对象
Class Person implements Comparable{
	int age;
	
	// ... 省略中间细节
	
	// 实现了 Comparable 接口中的 compareTo 方法
	@Override
    public int compareTo(Object o) {
        Person person = (Person)o;
        if (this.age > person.age) return 1;
        else if (this.age < person.age) return -1;
        else return 0;
    }
}

之后,便可以通过 Arrays.sort 以 age 升序排序 Person 对象

// 创建 Person 数组
Person[] persons = new Person[]{new Person(18), new Person(20)};
// 按照 age 升序排序 Person 对象
Arrays.sort(persons);

1.2.2 实现 Comparator 接口中的 compare 函数

同基本类型降序排序部分大同小异,在此不作叙述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值