簡體   English   中英

Java 8流和簡單類型

[英]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 LongStreammap方法返回一個LongStream (即源LongStream每個long元素都映射到目標LongStreamlong元素)。 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<String> ,您可以調用map並根據mapper的返回類型返回Stream<R> 但是在LongStreammap將始終返回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())

您需要更改mapmapToObj如果你想改變LongStreamStream<Long> (或致電LongStream.boxed()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM