Java Comparator类用于对数组进行排序

56

假设我们有以下二维数组:

int camels[][] = new int[n][2];

如何声明Java的Comparator类来使用Arrays.sort(camels, comparator)按照第一个元素降序排序数组?参考compare函数如下:

@Override public int compare(int[] a, int [] b)
{
    return b[0] - a[0];
}
5个回答

109

[...] 如何声明Java Comparator类以按其第一个元素降序对数组进行排序[...]

这是一个使用Java 8的完整示例:

import java.util.*;

public class Test {

    public static void main(String args[]) {

        int[][] twoDim = { {1, 2}, {3, 7}, {8, 9}, {4, 2}, {5, 3} };

        Arrays.sort(twoDim, Comparator.comparingInt(a -> a[0])
                                      .reversed());

        System.out.println(Arrays.deepToString(twoDim));
    }
}

输出:

[[8, 9], [5, 3], [4, 2], [3, 7], [1, 2]]

针对Java 7,您可以这样做:

Arrays.sort(twoDim, new Comparator<int[]>() {
    @Override
    public int compare(int[] o1, int[] o2) {
        return Integer.compare(o2[0], o1[0]);
    }
});

如果你不幸在工作中使用的是Java 6或更早版本,则应该执行以下操作:

Arrays.sort(twoDim, new Comparator<int[]>() {
    @Override
    public int compare(int[] o1, int[] o2) {
        return ((Integer) o2[0]).compareTo(o1[0]);
    }
});

抱歉翻出一个旧的帖子,但是为什么在返回比较方法时需要强制转换为整数? - Evolutionary High
1
@EvolutionaryHigh,因为你不能在int上调用.compareTo - aioobe
此外,在Java 5中,@Override注释无法工作。https://dev59.com/V3NA5IYBdhLWcg3wX8rk - jontro
哦天啊。这样一个小用例已经从4演变到5,再到6,再到7,最后到8 :-) 挺有趣的。 - aioobe
我认为Swift中的闭包可能是指使用匿名函数来创建自己的格式,例如sort() {$1 > $2} - Zhou Haibo
如果我想按第一个元素的递增顺序对这个二维数组进行排序,并且如果两个一维数组的第一个元素相同,则按第二个元素对它们进行排序,那么我应该在上面的代码中添加什么? - sam2611

9
@aioobe的回答非常好。我只想再补充一种Java 8的方法。
int[][] twoDim = { { 1, 2 }, { 3, 7 }, { 8, 9 }, { 4, 2 }, { 5, 3 } };

Arrays.sort(twoDim, (int[] o1, int[] o2) -> o2[0] - o1[0]);

System.out.println(Arrays.deepToString(twoDim));

对我来说,使用Java 8语法是直观且易于记忆的。


9

我刚刚尝试了这个解决方案,甚至无需编写int。

int[][] twoDim = { { 1, 2 }, { 3, 7 }, { 8, 9 }, { 4, 2 }, { 5, 3 } };
Arrays.sort(twoDim, (a1,a2) -> a2[0] - a1[0]);

这个东西也可以用,它会自动检测字符串的类型。

0

java.nio.IntBuffer#wrap(int[]) 提供了一种优秀的内置方法来比较两个 int[] 实例,因为 IntBuffer 既是一个轻量级的 int[] 实例包装器,实现了 Comparable 接口。与其他答案中的示例相比,将其与其他内置的 Comparator 特性结合使用具有以下几个优点:

  • 比较所有子数组元素
  • 支持可变长度的子数组
  • 支持 null 数组元素

此示例按降序对数组进行排序,将 null 数组元素放在最后:

int[][] twoDim = {{1, 2}, {3, 7}, {8, 9}, {4, 2}, null, {5, 3}, {4}};
System.out.println("Unsorted: " + Arrays.deepToString(twoDim));

Comparator<int[]> c = Comparator.nullsFirst(Comparator.comparing(IntBuffer::wrap));
Arrays.sort(twoDim, c.reversed());
System.out.println("Sorted: " + Arrays.deepToString(twoDim));

输出:

Unsorted: [[1, 2], [3, 7], [8, 9], [4, 2], null, [5, 3], [4]]
Sorted: [[8, 9], [5, 3], [4, 2], [4], [3, 7], [1, 2], null]

-1

这里是对日期数组进行排序的ArrayList。 也许有人会在某个时候需要它。

List <Date[]> sortedDateList = new ArrayList<>(/* initialization */);
Collections.sort(sortedDateList, new Comparator<Date[]>() {
    @Override
    public int compare(Date[] d1, Date[] d2) {
        return (d1[0].compareTo(d2[0]));
    }
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接