【发布时间】:2016-08-15 23:01:34
【问题描述】:
(这可能与https://stackoverflow.com/a/30312177/160137有关,但我恐怕还是不明白。所以我这样问我的问题,希望它会导致我能更多的答案容易理解。)
通常,当我有一个 Stream 时,我可以使用 Collectors 类中的一种静态方法将其转换为一个集合:
List<String> strings = Stream.of("this", "is", "a", "list", "of", "strings")
.collect(Collectors.toList());
但是,正如其他人所注意到的,类似的过程不适用于原始流:
IntStream.of(3, 1, 4, 1, 5, 9)
.collect(Collectors.toList()); // doesn't compile
我可以这样做:
IntStream.of(3, 1, 4, 1, 5, 9)
.boxed()
.collect(Collectors.toList());
或者我可以这样做:
IntStream.of(3, 1, 4, 1, 5, 9)
.collect(ArrayList<Integer>::new, ArrayList::add, ArrayList::addAll);
问题是,为什么 Collectors.toList() 不对原始流执行此操作?是不是没有办法指定包装类型?如果是这样,为什么这也不起作用:
IntStream.of(3, 1, 4, 1, 5, 9)
.collect(Collectors.toCollection(ArrayList<Integer>::new)); // nope
任何见解将不胜感激。
【问题讨论】:
-
因为(即使在 Java-8 中),也没有
List<int>。原始类型不是Object(s)。 -
签名中的泛型根本不适用于原始类型。就这么简单。
-
显式调用
boxed()和允许原始流上的盒装收集器在功能上没有区别。如果您问为什么为了方便而不允许这样做,也许设计师想让拳击变得显而易见。 -
@ElliottFrisch,Dici 我认为 OP 明白这一点。问题是为什么不能在原始流上使用盒装收集器?例如,
IntStream可能会接受Collector<? super Integer, A, R>。 -
@shmosel 我想知道编译器是否甚至允许您所谓的“盒装收集器”(尽管我不确定您的意思)。他们本可以复制所有收集器以使它们成为原始收集器,但这不是很好
标签: java java-8 collectors