匿名类替换为lambda表达式

Tom*_*Tom 21 java lambda anonymous-class java-8

我有一个使用Java 8新流功能的示例代码(获取一系列int值1 .. 20,跳过前9个,然后取剩余10个,每个int值:减1并乘以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()));
Run Code Online (Sandbox Code Playgroud)

输出如下:

[18, 20, 22, 24, 26, 28, 30, 32, 34, 36]
Run Code Online (Sandbox Code Playgroud)

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

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()));
Run Code Online (Sandbox Code Playgroud)

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

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

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

编译错误

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

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

jpv*_*vee 15

您必须将第一个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()));
Run Code Online (Sandbox Code Playgroud)


nob*_*beh 11

我设法编译代码如下(虽然使用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()));
Run Code Online (Sandbox Code Playgroud)

我理解你的兴趣能够编写的代码不宣firstsecond; 然而,IntUnaryOperator是一个FunctionalInterface基于Java的编译器是如何工作的,一个FunctionalInterface需要有一个"上下文"能够组成你想要的方式.这就是为什么使用原始代码片段Java编译器无法将lamda表达式映射到完全正确的实例IntUnaryOperator.

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


isn*_*bad 11

另一种解决方案是使用static IntUnaryOperator.identity()作为起点:

IntUnaryOperator.identity().andThen(v -> v - 1).andThen(i -> i * 2)
Run Code Online (Sandbox Code Playgroud)

使用静态导入,您也可以使用identity()!

如果IntUnaryOperator有像...那样的静态方法

static IntUnaryOperator first(IntUnaryOperator op) { return op; }
Run Code Online (Sandbox Code Playgroud)

......我们可以简单地写:

IntUnaryOperator.first(v -> v - 1).andThen(i -> i * 2)
Run Code Online (Sandbox Code Playgroud)