java - 如何按两个字段对数组列表进行排序
问题描述
我有双数组列表,我想根据第一个和最后一个字段对其进行排序。到目前为止,我只能按数组的 1 个元素对其进行排序。
真实状态:
0 1 2
------- ------- -------
78 100 0
78 100 1
0 100 0
104 100 1
预期的:
0 1 2
------- ------- -------
0 100 0
78 100 1
78 100 0
101 100 1
我想根据数组的第一个元素的值对字段进行排序。如果第 1 和第 2 的值相等,我想根据第 3 个元素排序,其中第一个应该是 1,然后是 0(只有 1 和 0 值)
List<Double[]> splitList = new ArrayList<>();
Double[] tmp1 = { 78d, 100d, 0d };
Double[] tmp2 = { 78d, 100d, 1d };
Double[] tmp3 = { 0d, 100d, 0d };
Double[] tmp4 = { 104d, 100d, 1d };
splitList.add(tmp1);
splitList.add(tmp2);
splitList.add(tmp3);
splitList.add(tmp4);
splitList.sort(Comparator.comparingDouble(a -> a[0]));
这个根据第一个元素对我进行排序。我找到了按两个元素排序的解决方案https://stackoverflow.com/a/26865122/9774735所以我试了一下:
splitList.sort(Comparator.comparingDouble(a -> a[0]).thenComparingDouble(b -> b[2]));
它向我输出了一个错误:
Multiple markers at this line
- The type of the expression must be an array type but it resolved
to Object
- The type of the expression must be an array type but it resolved
如何比较数组列表?
解决方案
似乎 java 编译器在推断泛型类型时存在问题,您有一些选项可以克服这个问题:
使用带有模式的类型提示
Class.<GenericType>.method(Arguments)
:splitList.sort(Comparator.<Double[]>comparingDouble(a -> a[0]).thenComparingDouble(b -> b[2]));
声明 lambda 参数类型(首先声明它似乎就足够了):
splitList.sort(Comparator.comparingDouble((Double[] a) -> a[0]).thenComparingDouble(b -> b[2]));
阅读您的评论后,您想反转最后的比较,可以这样完成:
Comparator.<Double[]>comparingDouble(a -> a[0])
.thenComparing(Comparator.<Double[]>comparingDouble(b -> b[2]).reversed())
这很混乱,你最好使用这样的东西:
splitList.sort((a, b) -> {
int c = Double.compare(a[0], b[0]);
return c == 0 ? Double.compare(b[2], a[2]) : c;
});