所不同的是以下內容:
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