您可以在某个实用程序类中编写自己的收集器并使用它:
public static > Collector> intersecting() {
class Acc {
Set result;
void accept(S s) {
if(result == null) result = new HashSet<>(s);
else result.retainAll(s);
}
Acc combine(Acc other) {
if(result == null) return other;
if(other.result != null) result.retainAll(other.result);
return this;
}
}
return Collector.of(Acc::new, Acc::accept, Acc::combine,
acc -> acc.result == null ? Collections.emptySet() : acc.result,
Collector.Characteristics.UNORDERED);
}
用法非常简单:
Set result = Arrays.stream(collections).collect(MyCollectors.intersecting());
但请注意,收集器不能短路:即使中间结果是空集合,它仍将处理流的其余部分.
这种收集器可以在我的免费StreamEx库中找到(见MoreCollectors.intersecting()).它适用于像上面这样的普通流,但如果你将它与StreamEx(扩展普通流)一起使用,它就会变成短路:处理实际上可能会提前停止.