gpt4 book ai didi

java - 尽可能在 Collectors 中使用 Characteristics.UNORDERED 重要吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:29:44 27 4
gpt4 key购买 nike

因为我经常使用流,其中一些流处理大量数据,所以我认为预先分配一个近似大小的基于集合的收集器是个好主意,以防止昂贵的重新分配作为集合成长。所以我想出了这个,以及其他集合类型的类似方法:

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() 的实现设置了 Characteristics 枚举,而 Collectors.toCollection() 没有:Characteristics.UNORDEREDCollectors.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. 如果我想让它理想地工作,是否有必要应用无序特性?我读过 a question on this forum我了解到无序特征不再反向传播到 Stream 中。它仍然有用吗?

最佳答案

首先,UNORDERED Collector的特征有没有帮助性能,没有别的。 Collector 没有问题不具有该特征但不取决于遇到的顺序。

此特性是否有影响取决于流操作本身和实现细节。虽然当前的实现可能不会从中汲取太多优势,但由于反向传播的困难,这并不意味着 future 的版本不会。当然,已经无序的流不受 UNORDERED 的影响。 Collector 的特征.并非所有流操作都有可能从中受益。

所以更重要的问题是不阻止这种潜在的优化(也许在将来)有多重要。

请注意,还有其他未指定的实现细节,会影响您的第二个变体的潜在优化。 toCollection(Supplier)收集器具有未指定的内部工作原理,仅保证提供由 Supplier 生成的类型的最终结果。 .相比之下,Collector.of(() -> new HashSet<>(initialCapacity), Set::add, (c1, c2) -> { c1.addAll(c2); return c1; }, IDENTITY_FINISH, UNORDERED)精确定义收集器应该如何工作,并且还可能阻碍收集器的内部优化产生 future 版本的收集器。

这是一种在不触及 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);
}

这限制了提供您的特征所需的努力(如果这是一个反复出现的问题),因此提供它们不会有什么坏处,即使您不知道它会产生多大的影响。

关于java - 尽可能在 Collectors 中使用 Characteristics.UNORDERED 重要吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37063512/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com