[英]Java 8 streams and simple types
任何人都可以向我解釋為什么以下不起作用:
long la[] = new long[] {1,2,3};
Arrays.stream(la).map(Long::valueOf).collect(Collectors.toSet());
這樣做:
String la[] = new String[] {"1","2","3"};
Arrays.stream(la).map(Long::valueOf).collect(Collectors.toSet());
前者給出了編譯錯誤,而后者沒有。 編譯錯誤是如此神秘(Eclipse),我無法理解它。
Arrays.stream(la)
執行方法public static LongStream stream(long[] array)
,其產生一個LongStream
。 LongStream
的map
方法返回一個LongStream
(即源LongStream
每個long
元素都映射到目標LongStream
的long
元素)。 LongStream
沒有接受單個參數的collect
方法,這就是collect(Collectors.toSet())
不通過編譯的原因。
如果你使用mapToObj
它應該工作:
Set<Long> set = Arrays.stream(la).mapToObj(Long::valueOf).collect(Collectors.toSet());
你的第二個片段工作,因為這里Arrays.stream
產生Stream
的引用類型( Stream<String>
),其map
方法產生另一個Stream
的引用類型( Stream<Long>
你的情況)。 這里, Stream
有一個collect
方法接受一個參數 - collect(Collector<? super T, A, R> collector)
- 所以collect(Collectors.toSet())
可以工作。
代碼看起來一樣。 在這兩種情況下,被調用的方法Arrays.stream
實際上是不同的:
stream(long[])
,它返回一個LongStream
。 這是long
元素流的原始特化。 stream(T[])
(其中T = String
)返回Stream<String>
在Stream<String>
,您可以調用map
並根據mapper的返回類型返回Stream<R>
。 但是在LongStream
, map
將始終返回LongStream
,即原始特化。 會發生什么是Long::valueOf
會將你的long
元素變成一個Long
對象,然后它會自動解包成long
; 實際上,除了box / unbox之外,該呼叫什么都不做。
然后問題出現在collect
呼叫上。
LongStream.collect
需要3個參數 Stream.collect
有一個3參數方法,但也有一個參數方法,它是你用.collect(Collectors.toSet());
調用的方法.collect(Collectors.toSet());
。 所以你不能調用.collect(Collectors.toSet());
在LongStream
。 這不會編譯:它需要3個參數。
你可以做的是在LongStream
上調用mapToObj
而不是map
:這個方法聲明從mapper的返回類型返回Stream<R>
(而不是LongStream
)。 在這種情況下,映射器是Long::valueOf
,它返回一個Long
對象,因此它將返回Stream<Long>
。
回顧一下:
long la[] = new long[] {1,2,3};
Arrays.stream(la).map(Long::valueOf).collect(Collectors.toSet());
//^--LongStream----^^---LongStream----^^ error
String la[] = new String[] {"1","2","3"};
Arrays.stream(la).map(Long::valueOf).collect(Collectors.toSet());
//^-Stream<String>-^^--Stream<Long>--^^---- successful call -----^
long la[] = new long[] {1,2,3};
Arrays.stream(la).mapToObj(Long::valueOf).collect(Collectors.toSet());
//^--LongStream----^^-----Stream<Long>-----^^---- successful call -----^
為了回答第一個沒有編譯的原因,這會創建一個LongStream
:
Arrays.stream(la)
這需要每個long
,創建一個Long
包裝器,然后將它重新打包回long
。 Stream仍然是一個LongStream
:
.map(Long::valueOf)
這會將單個參數傳遞給LongStream.collect
,但由於LongStream.collect
需要3個參數,因此會失敗:
.collect(Collectors.toSet())
您需要更改map
以mapToObj
如果你想改變LongStream
成Stream<Long>
(或致電LongStream.boxed()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.