Eug*_*ene 6 java java-8 java-stream java-9
我正在寻找Collectors.toSetjdk-8下的实现,并且几乎看到了显而易见的事情:
public static <T> Collector<T, ?, Set<T>> toSet() {
return new CollectorImpl<>(
(Supplier<Set<T>>) HashSet::new,
Set::add,
(left, right) -> { left.addAll(right); return left; }, // combiner
CH_UNORDERED_ID);
Run Code Online (Sandbox Code Playgroud)
看combiner一下; 这已经在这里讨论过,但想法是这样的a combiner folds from the second argument into the first.这显然发生在这里.
但后来我调查了jdk-9实现并看到了这个:
public static <T> Collector<T, ?, Set<T>> toSet() {
return new CollectorImpl<>(
(Supplier<Set<T>>) HashSet::new,
Set::add,
(left, right) -> {
if (left.size() < right.size()) {
right.addAll(left); return right;
} else {
left.addAll(right); return left;
}
},
CH_UNORDERED_ID);
Run Code Online (Sandbox Code Playgroud)
现在为什么会发生这种情况有点明显 - 添加时间更短less elements to a bigger Set, then the other way around.但这是否真的比普通便宜addAll,考虑分支的额外开销呢?
这也打破了关于总是向左折叠的法律 ......
有人能在这里说清楚吗?
Hol*_*ger 10
的组合器功能Collector将收到的left和right适当的,如果有遇到以维持,但是,它是到Collector,怎么会实际结合这两个参数.
该文件规定:
一个接受两个部分结果并合并它们的函数.组合器函数可以将状态从一个参数折叠到另一个参数并返回该参数,或者可以返回新的结果容器.
为了收集到List,这将是灾难性的,如果我们只是换left.addAll(right)到right.addAll(left),但无序Set,也没关系.所述toSet()集电极连报告UNORDERED暗示所述特征Stream(或任何客户端代码),它甚至不会无论哪个参数作为提供left或right,所以并行流可以结合任意的部分结果,无论已完成第一,换句话说,它即使源具有遭遇顺序(Java 8的实现不使用该机会),也可能表现得像无序流.
关于它是否值得...我们正在比较一个额外的分支与可能add保存的数千个操作,每个分支在内部承载多个条件分支......
| 归档时间: |
|
| 查看次数: |
329 次 |
| 最近记录: |