The stream()
, map()
, collect()
,所有其他流方法都依赖于泛型类型才能正常工作。如果您使用原始类型作为输入,那么所有泛型都会被删除,并且所有内容都会变成原始类型。例如,如果您有一个List<String>
,调用stream()
方法给你一个类型的对象Stream<String>
.
但如果你从原始类型开始List
,然后调用stream()
给你一个原始类型的对象Stream
反而。
The map()
方法有这样的声明:
<R> Stream<R> map(Function<? super T,? extends R> mapper)
但由于它是在原始状态下调用的Stream
,就好像声明是
Stream map(Function mapper)
所以调用的结果map()
简单来说就是一个Stream
。的签名collect()
充满了泛型:
<R> R collect(Supplier<R> supplier,
BiConsumer<R,? super T> accumulator,
BiConsumer<R,R> combiner)
当使用原始类型调用时,它会被擦除
Object collect(Supplier supplier,
BiConsumer accumulator,
BiConsumer combiner)
所以你的流管道的返回类型是Object
当其来源是原始类型时。显然这不兼容ArrayList<String>
你会得到一个编译错误。
要解决此问题,请尽快将您的类型带入通用世界。这可能会涉及未经检查的强制转换,您可能应该抑制该警告。当然,仅当您确定返回的集合仅包含预期类型的对象时才执行此操作。
此外,如Hank D https://stackoverflow.com/a/37215169/1441122指出,toList()
收集器返回一个List
,不是一个ArrayList
。您可以将返回值分配给类型的变量List
,或者你可以使用toCollection()
创建一个实例ArrayList
明确地。
以下是包含这些修改的代码:
@SuppressWarnings("unchecked")
ArrayList<Integer> l = (ArrayList<Integer>)getRawArrayList();
l.add(1);
l.add(2);
ArrayList<String> l2 = l.stream()
.map(Object::toString)
.collect(Collectors.toCollection(ArrayList::new));