所不同的是以下内容:
lambda表达式看起来像
parameters -> expression
或
parameters -> { block }
其中任一block
返回一个值 - 或它不适用于类似void
的行为。
换句话说,一个拉姆达parameters -> expression
相当于parameters -> { return expression; }
如果expression
具有非空隙型或parameters -> { expression; }
如果expression
具有空隙的类型(如System.out.printf()
)。
你的第一个版本主要使用表达式有一些开销:
i -> i = i * 2
可以降低到i -> i * 2
,为i =
分配仅仅是不必要的,因为i
随即消失,并且不使用任何进一步。
它就像
Integer function(Integer i) {
i = i * 2;
return i;
}
或
Integer function(Integer i) {
return (i = i * 2);
}
这可以简化为
Integer function(Integer i) {
return i * 2;
}
所有这些例子将匹配接口UnaryOperator<Integer>
其是用于Function<Integer, Integer>
一种特殊情况。
相反,你第二个例子是像
XY function(int i) {
i = i * 2;
}
不工作:
- 要么
XY
是void
(这将使一个Consumer<Integer>
不与.map()
适合)
- 或
XY
确实是Integer
(然后返回语句丢失)。
这个值的需求在哪里(编译代码除外)?
好,.forEach(System.out::println);
需要一个值...
所以,一切都可以被转换成Function<T, R>
可以给一个T
流的.map()
,导致R
流:
Stream.of(1, 2, 3).map(i -> i * 2)
Stream.of(1, 2, 3).map(i -> { return i * 2; })
把你给Integer
转Integer
,再给你Stream<Integer>
。你注意到他们是装盒的?
其他方式将
// turn a Stream<Integer> to an IntStream with a
// int applyAsInt(Integer i) aka ToIntFunction<Integer>
Stream.of(1, 2, 3).mapToInt(i -> i * 2)
Stream.of(1, 2, 3).mapToInt(i -> { return i * 2; })
// turn an IntStream to a different IntStream with a
// int applyAsInt(int i) aka IntUnaryOperator
IntStream.of(1, 2, 3).map(i -> i * 2)
IntStream.of(1, 2, 3).map(i -> { return i * 2; })
// turn an IntStream to a Stream<Integer> with a
// Integer apply(int i) aka IntFunction<Integer>
IntStream.of(1, 2, 3).mapToObj(i -> i * 2)
IntStream.of(1, 2, 3).mapToObj(i -> { return i * 2; })
所有这些例子的共同点是,他们得到的值,并产生相同或不同类型的值。 (注意这些实施例是如何使用自动装箱和AutoUnboxing根据需要)
OTOH,一切都可以被转换成Consumer<T>
可以给予一个T
流的.map()
,其可以是任何形式的λ的其产生的void
表达:
.forEach(x -> System.out.println(x))
.forEach(x -> { System.out.println(x); }) // no return as you cannot return a void expression
.forEach(System.out::println) // shorter syntax for the same thing
.forEach(x -> { }) // just swallow the value
考虑到这一点,很容易地看到,void
表达型的λ不能被给予.map()
,和具有非void
类型的λ不能被给予forEach()
。
“无支撑”版本要求箭头符号的右侧是一个有效的Java表达式(注意:expression,not statement!);这是它工作的原因。但最后都做同样的事情。 – fge