2 回答
TA貢獻1804條經驗 獲得超2個贊
Collecto.toList()分配ListusingArrayList::new這是一個非常便宜的操作,因為ArrayList在插入元素之前實際上不會分配支持數組。構造函數所做的就是將內部Object[]字段初始化為靜態創建的空數組的值。只有在插入第一個元素時,實際的后備數組才被初始化為其“初始大小”。
那么為什么要經歷避免這種結構的痛苦呢?這聽起來像是過早的優化。
如果您非常擔心 GC 壓力,請不要使用 Streams。流和收集器本身的創建可能比列表要“昂貴”得多。
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;
}
添加回答
舉報
