匿名类替换为 lambda 表达式

2022-09-02 03:23:36

我有使用Java 8新流功能的示例代码(获取int值范围1 .. 20,跳过前9个,然后取剩余的10个,每个int值:减少一乘以2)。

System.out.println(Arrays.toString(
    IntStream.rangeClosed(1, 20).skip(9).limit(10).map((new IntUnaryOperator() {
        @Override
        public int applyAsInt(int operand) {
            return operand - 1;
        }
    }).andThen(new IntUnaryOperator() {
        @Override
        public int applyAsInt(int operand) {
            return operand * 2;
        }
    })).toArray()));

输出如下:

[18, 20, 22, 24, 26, 28, 30, 32, 34, 36]

现在我想用 Lambda 表达式替换匿名类。以下转换工作正常(第二个匿名类替换为lambda表达式),我得到相同的输出:i -> i * 2

System.out.println(Arrays.toString(
    IntStream.rangeClosed(1, 20).skip(9).limit(10).map((new IntUnaryOperator() {
        @Override
        public int applyAsInt(int operand) {
            return operand - 1;
        }
    }).andThen(i -> i * 2)).toArray()));

但是,当我将第一个匿名类替换为 lambda 表达式时:

System.out.println(
    Arrays.toString(
        IntStream.rangeClosed(1, 20).skip(9).limit(10)
            .map((v -> v - 1).andThen(i -> i * 2)).toArray()));

我无法编译我的代码。错误说Operator '-' cannot be applied to '<lambda parameter>', 'int'

Compilation error

您知道如何将两个 lambda 表达式与 ?IntUnaryOperator.andThen

我知道我可以使用... 这工作正常,但我想找出如何使用lambdas(如果可能的话)。.limit(10).map(v -> v - 1).map(i -> i * 2).toArray() ...IntUnaryOperator.andThen


答案 1

您必须将第一个 lambda 表达式显式转换为 IntUnaryOperator。以下代码有效:

System.out.println(
        Arrays.toString(
                IntStream.rangeClosed(1, 20).skip(9).limit(10)
                        .map(((IntUnaryOperator) v -> v - 1).andThen(i -> i * 2)).toArray()));

答案 2

我设法将代码编译如下(尽管使用eclipse实验版本):

IntUnaryOperator first = v -> v - 1;
IntUnaryOperator second = i -> i * 2;
System.out.println(Arrays.toString(IntStream.rangeClosed(1, 20).skip(9)
                .limit(10).map(first.andThen(second)).toArray()));

我理解你的兴趣,能够编写代码而不声明和;然而,根据Java编译器的工作方式,a需要有一个“上下文”才能按照你想要的方式进行组合。这就是为什么使用原始代码片段,Java编译器无法将 lamda 表达式精确映射到 的实例。firstsecondIntUnaryOperatorFunctionalInterfaceFunctionalInterfaceIntUnaryOperator

有关更长的讨论,请查看此主题:http://mail.openjdk.java.net/pipermail/jdk8-dev/2013-June/002668.html


推荐