开发者社区> 问答> 正文

这里的类型推导是怎样一个逻辑?

这里的类型推导是怎样一个逻辑?

这里需要对这样一个二维数组进行排序:

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

如下,像这样写类型推导能够完成:

// int[] -> T, T[]
Arrays.sort(arr, Comparator.comparing(item -> item[0] % 2));

但是这样就不行了:

Arrays.sort(arr, Comparator.comparing(item -> item[0] % 2).thenComparing(item -> item[1] % 3));

这是为什么呢?

展开
收起
问问小秘 2020-01-09 17:59:36 1013 0
1 条回答
写回答
取消 提交回答
  • 首先看 Compartor#comparing 的方法签名:

    public static <T, U extends Comparable<? super U>> Comparator comparing(
    Function<? super T, ? extends U> keyExtractor)
    { ... } 注意到 keyExtractor 是一个 Function.

    再来看 Arrays.sort 的能匹配题目环境的方法签名:

    public static void sort(T[] a, Comparator<? super T> c) { ... } 结合起来,即 a(int[][]) 的类型决定了 T(int[]),这要求第二个参数的类型必须为 Compartor<? super int[]>,这就确定了 comparing 方法参数(Function<? super T, ? extends U>) 第一个泛型参数必须是 int[] 类型.

    问题被简化为,给一个下面的表达式,该怎么匹配 Function<int[], ? extends U>:

    item -> item[1] % 2 已知 item 为 int[],则 item[x] 即为 int,则 item[1] % 2 必定为 int,但必须装箱成 Integer 才能作为泛型参数.

    那么对于

    Arrays.sort(arr, Comparator.comparing(item -> item[0] % 2).thenComparing(item -> item[1] % 3)); 为什么推导不出来,结合前面所说,现在要匹配 Arrays.sort(T[], Compartor<? super T>) 方法,就要求

    Compartor.comparing(item -> item[0] % 2) .thenComparing(item -> item[1] % 3) 最终是个 Compartor<int[]>.

    我们手动推一下:

    先来看一下 thenComparing 的方法签名:

    default <U extends Comparable<? super U>> Comparator thenComparing(
    Function<? super T, ? extends U> keyExtractor)
    { ... } 所以现在 T 为 int[],U 的类型是什么都无所谓了,因为这里的 T 与前面 Compartor.comparing 里的 T 是同一个.

    那么为什么 IDE、编译器推导不出来呢?

    因为:它们没办法从后往前推导.

    编译器在编译一个 java 文件时,会进行类型检查并擦除泛型.

    问题就在于,在第一个 Compartor.comparing 时,没有足够的信息让编译器知道 T 是什么类型,编译器会认为表达式 item -> item[0] % 2 是不被允许的(不知道 T 的类型那么就当作 Object 处理,而 Object 不是一个 Array type,且不支持 % 运算符)从而报错,这时就已经阻断了编译进程,没去管后面的东西.

    所以我们只需要提前告诉编译器 comparing 使用的 T 是什么就行了:

    Arrays.sort(arr, Comparator.<int[], Integer>comparing(item -> item[0] % 2) .thenComparing(item -> item[1] % 3));

    2020-01-09 18:07:33
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
重新定义计算的边界 立即下载
继承与功能组合 立即下载
低代码开发师(初级)实战教程 立即下载

相关实验场景

更多