Arrays.sort 的 @Override 在 Java 中如何工作?

How does this @Override for Arrays.sort work in Java?

Arrays.sort(people, (n1, n2) -> (n2[0] == n1[0])?  n1[1] - n2[1] : n2[0] - n1[0]);

Arrays.sort(people,new Comparator<int[]>(){
    @Override
    public int compare(int[] n1, int[] n2){
        return (n2[0] == n1[0])? n1[1] - n2[1]: n2[0] - n1[0];
    }
});

两者执行相同的操作。

输入:[[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]

输出:[[7,0],[7,1],[6,1],[5,0],[5,2],[4,4]]

我知道代码正在对它进行分组排序,但我不明白如何进行。我对 Java:

中的 PriorityQueue 同样感到困惑
PriorityQueue<Integer> pq = new PriorityQueue<>((a, b)-> b - a);

这个按降序排列。

谁能解释一下?如果有这样的 material,我在哪里可以学习或阅读更多关于这些 "overrides" 的信息?

箭头表示法是一个 lambda 函数,是相同 Comparator 实现的简写。这就是为什么您会看到相同的结果。这与 @Override 无关,您要问的是 Comparator 的实际工作方式。

比较器按以下顺序排序 2 个对象:

  • 负数,降序排列
  • 零,什么都不做
  • 正向,升序排序

因此对于优先级队列部分,当比较器对 1、4、6、3 进行排序时,它比较数组的元素,如果差异为负,则交换它们,例如它会交换 1 和 4、4 和 6 等

对于问题的第一部分,您使用的是这个实现: (n2[0] == n1[0])? n1[1] - n2[1]: n2[0] - n1[0]

对于大小为 2 的整数数组,您正在按以下方式比较数组。

  • 如果每个数组的第一个元素不相等,您将尝试按降序排序(即 [7, 0] 在 [4, 4] 之前)
  • 如果每个数组的第一个元素都相等,则说明您正在尝试排序 升序(即将 [7,0] 置于 [7,1] 之前)。

@Override 注解仅标记来自 subclass 的方法何时覆盖来自 superclass 的方法。在你的第二个例子中,你使用了一个叫做匿名内部 class 的东西,你基本上传递了一个 class 的实例,在你的例子 Comparator 中,它有一个名为 compare 的抽象方法.您正在适当地实现该方法功能,因此您不必创建一个新的 class 来扩展 Comparator class 等等。

您的第一个示例与第二个示例基本相同,但它的语法编写起来更短,看起来更简洁,也更易于阅读。第二个叫做Lambda expression.

以上 Arrays.sort 接受 2 个参数。第一个是需要排序的列表,第二个是比较器。 Comparator 是具有方法比较的功能接口。因为它是接口,所以你需要实现它(@Override 意味着你的实现正在覆盖这个方法)。 比较方法允许您决定排序策略(升序、降序、blabla)。

这是一个很大的飞跃,但您迟早应该了解接口、匿名 类 和 lambda 的。

oracle网站上有一套教程:

https://docs.oracle.com/javase/tutorial/java/IandI/index.html https://docs.oracle.com/javase/tutorial/java/javaOO/index.html

来自 Comparator.compareTo javadoc https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#compare-T-T-

Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.

So, what you see is expected. If we take two arguments from your input:
[7, 0], [4, 4]
the evaluation would be: 
n2[0] - n1[0] 
4 - 7 = -3 ( a negative integer)
It sees the first argument [7,0] is less than second argument [4,4] hence it is placed before in order.

Comparator method compare(T o1, T o2) 的 javadoc 说:

Returns:
a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.

“小于”和“大于”指的是排序顺序,不是数值,所以如果要降序排序,那么7就是“小于”5.

所以,下面展示了如何进行升序和降序排序:

// Ascending
(a, b) -> a - b

// Decending
(a, b) -> b - a

但是,您永远不应为此使用 - 减号运算符,因为它会导致溢出。使用 Integer.compare(int x, int y) method instead, or the equivalent methods on Long, Short, Byte, Double, and Float:

// Ascending
(a, b) -> Integer.compare(a, b)

// Decending
(a, b) -> Integer.compare(b, a)

下一部分是您的代码按 2 个字段排序,第一个字段降序,第二个字段升序:

(o1, o2) -> {
    if (o1.a != o2.a)
        return Integer.compare(o2.a, o1.a); // sort by a (descending)
    return Integer.compare(o1.b, o2.b); // secondary sort by b (ascending)
}

您的代码中的哪些是使用三元运算符完成的:

(o1, o2) -> o1.a != o2.a ? Integer.compare(o2.a, o1.a) : Integer.compare(o1.b, o2.b)

或者相反:

(o1, o2) -> o1.a == o2.a ? Integer.compare(o1.b, o2.b) : Integer.compare(o2.a, o1.a)