2 回答
![?](http://img1.sycdn.imooc.com/5458478b0001f01502200220-100-100.jpg)
TA贡献1804条经验 获得超2个赞
Collecto.toList()
分配List
usingArrayList::new
这是一个非常便宜的操作,因为ArrayList
在插入元素之前实际上不会分配支持数组。构造函数所做的就是将内部Object[]
字段初始化为静态创建的空数组的值。只有在插入第一个元素时,实际的后备数组才被初始化为其“初始大小”。
那么为什么要经历避免这种结构的痛苦呢?这听起来像是过早的优化。
如果您非常担心 GC 压力,请不要使用 Streams。流和收集器本身的创建可能比列表要“昂贵”得多。
![?](http://img1.sycdn.imooc.com/533e564d0001308602000200-100-100.jpg)
TA贡献1773条经验 获得超3个赞
我只考虑一种情况,除了Collectors.toList()计算成本高昂之外,否则使用:
... collect(Collectors.collectingAndThen(list -> {
list.isEmpty() ? null: list;
}))
但请记住,List如果缺少元素,使用它的人很可能会期望一个空的,而不是空的。
创造一个空ArrayList的非常便宜,在这里懒惰只会让事情变得更糟。
否则,如果您真的想要,这里有一个变体可以推迟到 null :
private static <T> List<T> list(Stream<T> stream) {
Spliterator<T> sp = stream.spliterator();
if (sp.getExactSizeIfKnown() == 0) {
System.out.println("Exact zero known");
return null;
}
T[] first = (T[]) new Object[1];
boolean b = sp.tryAdvance(x -> first[0] = x);
if (b) {
List<T> list = new ArrayList<>();
list.add(first[0]);
sp.forEachRemaining(list::add);
return list;
}
return null;
}
添加回答
举报