java - 为什么 Arrays.sort(T[] a, Comparator<? super T> c) 将 T 推断为二维数组的对象?

标签 java arrays java-8 comparator

如果我想对二维数组进行排序。 (只需重新排序行,不要触摸每行中的数据)。

在下面的片段中:所有 3 个案例都使用相同的 Arrays.sort(T[] a, Comparator<? super T> c)方法签名。案例 (a) 工作正常。但是,仅通过向第二个参数添加 if 条件,T 的推断就会改变。我无法理解为什么。

        // array contains 3 tuples, sort it by the first element, then second element
        int[][] array1 = new int[3][2];
        array1[0] = new int[]{1,2};
        array1[1] = new int[]{2,3};
        array1[2] = new int[]{2,4};

        // Case (a): compiles good, tuple is inferred as int[]
        Arrays.sort(array1, Comparator.comparingInt(tuple -> tuple[0]));  // Arrays.sort(T[] a, Comparator<? super T> c) correctly infers that T refers to int[]

        // Case (b.1): compile error: incompatible types
        // tuple is now inferred as Object, why?
        Arrays.sort(array1,
                (a1, a2) -> a1[0] == a2[0] ?
                        Comparator.comparingInt(tuple -> tuple[1]) : Comparator.comparingInt(tuple -> tuple[0]));  

        // Case (b.2): compile error: incompatible types
        Arrays.sort(array1, Comparator.comparingInt(tuple -> tuple[0]).thenComparingInt(tuple -> tuple[1])); 
        
        // Case (c): if downcast tuple[0] to ((int[])tuple)[0], then (b) works fine. 

更新:

  1. 受到评论的启发,我很快意识到案例 (b.1) 实际上是无效的。 (b.1) 中的 lambda 假设返回一个整数,而不是比较器。例如。 Arrays.sort(array1, (a1, a2) -> a1[0] == a2[0] ? 0 : 1);
  2. 在所有其他情况下,我看到 Comparator.<int[]>comparingInt(...)强制推论正确。

最佳答案

简短回答:编译器不够智能,无法通过如此复杂的表达式进行推断。它需要一些帮助来推断类型:

Arrays.sort(array1, Comparator.<int[]>comparingInt(tuple -> tuple[0]).thenComparingInt(tuple -> tuple[1]));

相关 JEP:http://openjdk.java.net/jeps/101

至于三元表达式的情况,我认为它需要进一步调整,因为你需要在 lambda 中返回一个 int,而不是一个 Comparator:

Arrays.sort(array1,
            (a1, a2) -> a1[0] == a2[0] ?
                    Comparator.<int[]>comparingInt(tuple -> tuple[1]).compare(a1, a2) :
                    Comparator.<int[]>comparingInt(tuple -> tuple[0]).compare(a1, a2));

关于java - 为什么 Arrays.sort(T[] a, Comparator<? super T> c) 将 T 推断为二维数组的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67208869/

相关文章:

java - 查找Java 8中列表的最大,最小,总和和平均值

java - 让程序等待直到单击按钮

java - 如何使用常量将 hibernate 实体映射到另一个实体

java - Eclipse:在特定文件夹中搜索文件(将其中的特定关键字作为搜索条件)的键盘快捷键是什么?

php - 在 Laravel/PHP 中将额外的字段插入数组

javascript - 更改数组字符串值的第一个(或任何)字符

java - 无法解析基于模块的 Maven 项目的依赖关系

javascript - 如何将数组中的前一项附加到下一项?

Java 1.8.20 编译器错误

Java 流 toArray() 转换为特定类型的数组