Java 数组,如何通过自定义实现倒叙排序?

2020-09-10 22:44:11 +08:00
 LeeReamond

如题,初学 java,熟悉语法过程中遇到问题,代码段如下

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] ns = {5,4,3,2,1};
        Arrays.sort(ns , (a,b) -> a>=b);
        System.out.println(Arrays.toString(ns));
    }
}

希望实现的效果:正序排序与倒叙排序。

按照其他语言的逻辑,给定的 sort 函数一般是用快排之类的算法,这种情况下如果要实现倒叙排序的话,一般是在后面输入一个自定义判断函数,用作判断大小。

然后在这段代码里这个排序函数就应该是看起来很像 js 的箭头函数的这个[(a,b) -> a>=b ]

代码无法运行,报错[运算符 '>=' 不能应用于 'T', 'T']。无法理解发生了什么,不理解为什么无法执行。另外关于这个类似箭头函数的,应该是 java 的 lambda 函数吧,不定义输入类型什么的真的没有搞错吗?

=========================================================

上文是整数排序,换成字符串的话就可以运行了,不理解为什么

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        String[] ns = {"5","4","3","2","1"};
        Arrays.sort(ns , (a,b) -> a.compareTo(b)); // 为什么用大于判断不行,用 string 的方法判断就行了
        System.out.println(Arrays.toString(ns));
    }
}
3325 次点击
所在节点    Java
16 条回复
EminemW
2020-09-10 23:22:38 +08:00
应该是这样 (a,b) -> {b-a}
EminemW
2020-09-10 23:26:09 +08:00
你看 Arrays.sort() 方法的参数就知道了,第二个参数是一个接口,这个接口要实现比较函数,这个函数返回值是一个整的。你写的 lambda 返回的是布尔型,当然不可以
LeeReamond
2020-09-11 00:01:47 +08:00
@EminemW 还是报错
![]( )
Cbdy
2020-09-11 00:16:42 +08:00
(a,b) -> b-a
LeeReamond
2020-09-11 00:27:19 +08:00
@Cbdy 报错,报错信息相同
KaraSalmon
2020-09-11 01:22:52 +08:00
数组用 Integer
aguesuka
2020-09-11 01:35:01 +08:00
这个很明显是因为 int 是基本类型不是对象,比较函数的参数是泛型对象。
lxychn
2020-09-11 01:45:26 +08:00
1. Arrays.sort() 不能应用于原始类型排序,int 是原始类型,String 不是
2. Arrays.sort()第二个参数传入是个 Comparator,用的是里面才 compare 方法,compare 方法返回的是 int,一般用负值,0,正值代表小于,等于,大于。compareTo()返回的也是 int
black11black
2020-09-11 01:48:19 +08:00
@aguesuka
@lxychn
感谢回复,Arrays.sort 如果不加 comparator 的话是可以对 int[]进行排序的,所以应该不是无法排序,所以原因应该是 comparator 无法应用于单纯 int 构成的数组?
ky11223344
2020-09-11 03:38:52 +08:00
编译时静态检查不通过,这里的 sort 是个泛型方法,编译器无法通过输入参数推出类型参数的值,如果尝试指明类型参数再 call 这个方法会得到更明确的错误提示,像 Arrays.<int>sort 会提示 primitive 不能作为类型参数,或 Arrays.<Integer>sort 会提示第一个参数类型 int[]不正确。不指明类型参数的话则类型参数 T 无法被推导,在 lambda 里调用 a - b 则编译器认为对两个未知的 T 类型值做只有 primitive 才有效的加减乘除等操作是无效的,所以就有那个错误提示。这里还有个问题就是输入参数的类型不匹配任何一个 sort 方法函数签名时,编译器是怎么知道你要调用的就是这个泛型方法
vicsun2020
2020-09-11 03:43:17 +08:00
Comparator 只接受包装类的比较,只用基础类型没法自定义排序
lxychn
2020-09-11 06:22:26 +08:00
@black11black
只考虑了这种特定情况。。是的,Arrays.sort()不加 Comparator 可以对 int[]递增排序,无法自定义排序。compare 和 compareTo 传入的是类。
daozhihun
2020-09-11 07:27:16 +08:00
1. 如果你不传 comparator,就是正序排列,如果是基本类型就是基本类型的比较器,如果是引用类型会自动调用 compareTo 方法去比较
2. 传入 comparator 才能实现你自己想要的排序方式,比如逆序或者其他的。
但是 comparator 这个重载方法的定义是 T[],你这个 int[]是基本类型的数组,无法转换成 Object[]
所以要么你自己把 int[]包装成 Integer[](用 stream ),要么你自己把数组反序。
没错,这就是 java 这个泛型蛋疼的地方
Mysqto
2020-09-11 08:30:31 +08:00
报错的原因是 Arrays.sort()不支持 primitive type, 你把 int 换成 Integer, 顺序倒叙都可以用 lambda
```java
Integer[] ns = {5,4,3,2,1};
Arrays.sort(ns , (a,b) -> b-a);
```

```java
Integer[] ns = {5,4,3,2,1};
Arrays.sort(ns , (a,b) -> a-b);
```
当然最简单的你想倒叙可以用 `Arrays.sort(ns , Comparator.reverseOrder());`
340244120w
2020-09-11 09:34:07 +08:00
Arrays.stream(ns).boxed().sorted(Comparator.reverseOrder());
xhq
2020-09-11 10:41:16 +08:00
使用 Guava
Ints.sortDescending(new int[]{1, 2, 3, 4});

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/705957

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX