![](/img/trans.png)
[英]Confusion about Characteristics.UNORDERED in Java 8 in action book
[英]Is it important to use Characteristics.UNORDERED in Collectors when possible?
由於我使用了很多流,其中一些處理大量數據,我認為預先分配基於集合的收集器大小是一個好主意,以防止隨着集合的增長而進行昂貴的重新分配。 所以我想出了這個,以及類似的其他集合類型:
public static <T> Collector<T, ?, Set<T>> toSetSized(int initialCapacity) {
return Collectors.toCollection(()-> new HashSet<>(initialCapacity));
}
像這樣使用
Set<Foo> fooSet = myFooStream.collect(toSetSized(100000));
我擔心的是Collectors.toSet()
的實現設置了一個Collectors.toCollection()
沒有的Characteristics
枚舉: Characteristics.UNORDERED
。 Collectors.toCollection()
沒有方便的變體來設置超出默認值的所需特性,並且由於可見性問題,我無法復制Collectors.toSet()
的實現。 因此,為了設置UNORDERED
特性,我不得不這樣做:
static<T> Collector<T,?,Set<T>> toSetSized(int initialCapacity){
return Collector.of(
() -> new HashSet<>(initialCapacity),
Set::add,
(c1, c2) -> {
c1.addAll(c2);
return c1;
},
new Collector.Characteristics[]{IDENTITY_FINISH, UNORDERED});
}
所以這里是我的問題:1。這是我唯一的選擇,為自定義toSet()
2之類的東西創建一個無序收集器。如果我希望它理想地工作,是否有必要應用無序特征? 我在這個論壇上讀到了一個問題,在那里我了解到無序特征不再向后傳播到Stream中。 它仍然有用嗎?
首先, Collector
的UNORDERED
特征是幫助表演而不是其他任何東西。 Collector
沒有這個特征但不依賴於遭遇順序沒有錯。
此特性是否具有影響取決於流操作本身和實現細節 。 雖然目前的實現可能不會從中消耗很多優勢,但由於反向傳播的困難,它並不意味着未來的版本不會。 當然,已經無序的流不受Collector
的UNORDERED
特性的影響。 並非所有流操作都有可能從中受益。
因此,更重要的問題是不要阻止這種潛在的優化(可能在將來)是多么重要。
請注意,還有其他未指定的實現細節,影響了第二個變體的潛在優化。 toCollection(Supplier)
收集器具有未指定的內部工作方式,僅保證提供Supplier
生產的類型的最終結果。 相比之下, Collector.of(() -> new HashSet<>(initialCapacity), Set::add, (c1, c2) -> { c1.addAll(c2); return c1; }, IDENTITY_FINISH, UNORDERED)
精確定義收藏家應該如何工作,也可能妨礙收集產生未來版本收藏家的內部優化。
因此,在不涉及Collector
的其他方面的情況下指定特性的方法將是最佳解決方案,但據我所知,現有API沒有提供簡單的方法。 但是你自己建立這樣的設施很容易:
public static <T,A,R> Collector<T,A,R> characteristics(
Collector<T,A,R> c, Collector.Characteristics... ch) {
Set<Collector.Characteristics> o = c.characteristics();
if(!o.isEmpty()) {
o=EnumSet.copyOf(o);
Collections.addAll(o, ch);
ch=o.toArray(ch);
}
return Collector.of(c.supplier(), c.accumulator(), c.combiner(), c.finisher(), ch);
}
用這種方法,很容易說,例如
HashSet<String> set=stream
.collect(characteristics(toCollection(()->new HashSet<>(capacity)), UNORDERED));
或提供您的工廠方法
public static <T> Collector<T, ?, Set<T>> toSetSized(int initialCapacity) {
return characteristics(toCollection(()-> new HashSet<>(initialCapacity)), UNORDERED);
}
這限制了提供你的特征所需的努力(如果它是一個反復出現的問題),所以即使你不知道它會產生多大的影響,提供它們也不會有什么壞處。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.