[英]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.