繁体   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