我有使用Java 8 new stream functionality的示例代码(获取一系列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()));
输出如下:
[18, 20, 22, 24, 26, 28, 30, 32, 34, 36]
现在我想用Lambda expressions替换匿名类。以下转换工作正常(第二个匿名类替换为i -> i * 2
lambda表达式),我得到相同的输出:
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'
您知道如何将两个lambda表达式与IntUnaryOperator.andThen
结合使用吗?
我知道我可以使用...... .limit(10).map(v -> v - 1).map(i -> i * 2).toArray() ...
但效果很好,但我想了解如何将IntUnaryOperator.andThen
与lambdas一起使用(如果可能的话)。
答案 0 :(得分: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()));
答案 1 :(得分: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()));
我理解您能够在不声明first
和second
的情况下编写代码的兴趣;但是,IntUnaryOperator
是FunctionalInterface
,根据Java编译器的工作原理,FunctionalInterface
需要有一个“上下文”才能按照您希望的方式进行组合。这就是为什么使用原始代码片段Java编译器无法将lamda表达式映射到IntUnaryOperator
的实例。
如需更长时间的讨论,请查看以下主题:http://mail.openjdk.java.net/pipermail/jdk8-dev/2013-June/002668.html
答案 2 :(得分:11)
另一种解决方案是使用静态IntUnaryOperator.identity()
作为起点:
IntUnaryOperator.identity().andThen(v -> v - 1).andThen(i -> i * 2)
使用静态导入,您也可以只使用identity()
!
如果IntUnaryOperator
有静态方法,例如......
static IntUnaryOperator first(IntUnaryOperator op) { return op; }
......我们可以简单地写一下:
IntUnaryOperator.first(v -> v - 1).andThen(i -> i * 2)