![](/img/trans.png)
[英]Java Stream: How to avoid add null value in Collectors.toList()?
[英]How to lazy initialize Collectors.toList() in java 8 stream api?
我想基於過濾器收集項目。 但是,如果找不到匹配項,則不應初始化結果列表。 我希望使用null而不是空列表。
List<String> match = list
.stream()
.filter(item -> item.getProperty == "match")
.collect(Collectors.toList());
if (match != null && !match.isEmpty()) {
//handle seldom match
}
問題:大多數時候我不會有比賽,導致收藏為空。 這意味着大多數情況下即使我不需要該列表,它也會被實例化。
Collecto.toList()
使用ArrayList::new
分配List
,這是非常便宜的操作,因為ArrayList
直到插入元素才真正分配后備數組。 構造函數所做的全部工作就是將內部Object[]
字段初始化為靜態創建的空數組的值。 僅當插入第一個元素時,實際的后備數組才被初始化為其“初始大小”。
那么,為什么要避免這種構造呢? 這聽起來像是過早的優化。
如果您非常擔心GC壓力,那就不要使用Streams。 與列表相比,創建流和收集器本身可能要“昂貴得多”。
我只是在考慮一個情況,即Collectors.toList()
之外的其他東西計算起來會很昂貴,否則請使用:
... collect(Collectors.collectingAndThen(list -> {
list.isEmpty() ? null: list;
}))
但是請記住,使用該List
人很可能期望在缺少元素的情況下為空,而不是null。
創建一個空的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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.