如何将DoubleStream收集到List中

19

我有以下代码:

Stream.of("1,2,3,4".split(",")).mapToDouble(Double::valueOf).collect(Collectors.toList());

我想要返回List<Double>

这段代码无法编译。

我发现了错误:

Error:(57, 69) java: method collect in interface java.util.stream.DoubleStream cannot be applied to given types;
  required: java.util.function.Supplier<R>,java.util.function.ObjDoubleConsumer<R>,java.util.function.BiConsumer<R,R>
  found: java.util.stream.Collector<java.lang.Object,capture#1 of ?,java.util.List<java.lang.Object>>
  reason: cannot infer type-variable(s) R
    (actual and formal argument lists differ in length)

如何解决这个问题?


2
如果你想要直接将结果收集到列表中,为什么不使用 map 而要使用 mapToDouble 呢?你只需要进行 String -> Double 的转换即可,而不必进行 String -> Double -> double -> Double 的转换。 - Alexis C.
1
什么很奇怪?你提供了一个函数 String -> Double,如果你想将它收集到一个 List 中,它必须是一个 Double - Alexis C.
Alexis C. DoubleStream原始流吗? - gstackoverflow
1
https://docs.oracle.com/javase/8/docs/api/java/util/stream/DoubleStream.html - Alexis C.
1个回答

39

您可以使用 boxed() 方法。它将 DoubleStream(原始 double 数组的流,由 mapToDouble 返回)映射为一个 Stream<Double>

Stream.of("1,2,3,4".split(",")).mapToDouble(Double::parseDouble).boxed().collect(Collectors.toList());
请注意,我将 Double::valueOf 更改为 Double::parseDouble:这可以防止由 Double.valueOf 返回的 Double 被取消装箱为原始类型 double
但是你为什么一开始要使用 mapToDouble 呢?你可以像这样使用 map:
Stream.of("1,2,3,4".split(",")).map(Double::valueOf).collect(Collectors.toList());

4
对于可能更大的数据流,我建议使用 Pattern.compile(",").splitAsStream("1,2,3,4,…"),因为它不需要创建数组即可生成流。 - Holger
2
@Holger,另一方面,.split(",")是一条快速路径,它不会创建正则表达式对象和Matcher。目前还不清楚在多少个标记的情况下splitAsStream将优于String.split... - Tagir Valeev
1
@Tagir Valeev:通常情况下,您无法确切地知道“大数量”门槛。但显然,随着生成的子字符串数量增加,您可以忽略单个模式/匹配器对象的开销。 - Holger
1
嗯,为什么不直接使用Stream.of(1,2,3,4)跳过分割呢? - Louis Wasserman
@Louis Wasserman:由于结果被收集到一个List中,使用Arrays.asList(1,2,3,4)会更简单,省略整个流的内容。但是,这对于这个流问题来说就不再是有用的示例代码了。此外,Stream.of(1,2,3,4)并不像你想象的那么高效。由于它是一个varargs方法调用,所以在调用Stream.of之前,生成的代码会创建和填充一个数组。相比之下,"1,2,3,4"是一个常量,可以通过单个指令加载,并且拆分发生在JRE库代码中... - Holger
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接