任何人都可以向我解释为什么以下情况不起作用:
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),我无法理解它。
答案 0 :(得分:2)
Arrays.stream(la)
执行生成LongStream
的方法public static LongStream stream(long[] array)
。 LongStream
map
方法返回LongStream
(即源long
的每个LongStream
元素都映射到long
元素在目标LongStream
)中。 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())
可以正常工作。
答案 1 :(得分:2)
代码看起来一样。在这两种情况下,被调用的方法Arrays.stream
实际上是不同的:
stream(long[])
,返回LongStream
。这是long
元素的流的原始特化。stream(T[])
(此处T = String
)返回Stream<String>
在Stream<String>
上,您可以调用map
并根据映射器的返回类型返回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());
上致电LongStream
。这不会编译:它需要3个参数。
您可以在map
上致电mapToObj
而不是LongStream
:此方法声明返回Stream<R>
(而不是LongStream
)从mapper的返回类型。在这种情况下,映射器为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 -----^
答案 2 :(得分:0)
为了回答第一个没有编译的原因,这会创建一个Arrays.stream(la)
:
long
这会花费每个Long
,创建一个long
包装器,然后将其解包回LongStream
。流仍然是.map(Long::valueOf)
:
LongStream.collect
这会将单个参数传递给LongStream.collect
,但失败是因为.collect(Collectors.toSet())
需要3个参数:
map
如果您想将mapToObj
更改为LongStream
(或致电Stream<Long>
)
LongStream.boxed()
更改为{{1}}