修改代码.查看 串行 和并行的 区别.
@Override public Supplier<Set<T>> supplier() { System.out.println("supplier invoked"); // return HashSet<T>::new;// 返回一个HasHSet容器. System.out.println("-----"); return HashSet::new; }结论:串行的时候,会生成单个初始容器 / 并行的时候,会生成多个初始容器.
关于串行和并行的效率问题并不是说串行的效率就一定比并行的效率低.这都是要看实际情况的.
最多会生成系统最大CPU核心
超线程技术
Collectors类方法详解题外话:当你具备一些底层基础知识之后,你看一些东西会觉得是理所当然的.
如果你不具备这些知识的话,是看不懂的.云里雾里的.
关注一下JDK提供的方法是怎么实现的.对于Collectors静态工厂类来说,其实现一共分为两种方式.
通过CollectorImpl来实现
通过reducing来实现 (reducing本身又是通过CollectorImpl来实现)
所以,所有的方法都是通过CollectorImpl来实现的.
4个变量
static final Set<Collector.Characteristics> CH_CONCURRENT_ID = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.CONCURRENT, Collector.Characteristics.UNORDERED, Collector.Characteristics.IDENTITY_FINISH)); static final Set<Collector.Characteristics> CH_CONCURRENT_NOID = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.CONCURRENT, Collector.Characteristics.UNORDERED)); static final Set<Collector.Characteristics> CH_ID = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH)); static final Set<Collector.Characteristics> CH_UNORDERED_ID = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.UNORDERED, Collector.Characteristics.IDENTITY_FINISH)); static final Set<Collector.Characteristics> CH_NOID = Collections.emptySet();toCollection()方法
public static <T, C extends Collection<T>> Collector<T, ?, C> toCollection(Supplier<C> collectionFactory) { return new CollectorImpl<>(collectionFactory, Collection<T>::add, (r1, r2) -> { r1.addAll(r2); return r1; }, CH_ID); }toList()方法.是toCollection的一种特例.
public static <T> Collector<T, ?, List<T>> toList() { return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add, (left, right) -> { left.addAll(right); return left; }, CH_ID); }toSet()方法.是toCollection的一种特例.
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; }, CH_UNORDERED_ID); }joining(): 融合成一个字符串. 此外,还有两个重载的.单参数的和多参数的.
public static Collector<CharSequence, ?, String> joining() { return new CollectorImpl<CharSequence, StringBuilder, String>( StringBuilder::new, StringBuilder::append, (r1, r2) -> { r1.append(r2); return r1; }, StringBuilder::toString, CH_NOID); }mapping() 映射函数
public static <T, U, A, R> Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper, Collector<? super U, A, R> downstream) { BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator(); return new CollectorImpl<>(downstream.supplier(), (r, t) -> downstreamAccumulator.accept(r, mapper.apply(t)), downstream.combiner(), downstream.finisher(), downstream.characteristics()); }
collectingAndThen() 收集,并且做处理
原理:把IDENTITY_FINISH标识符给去掉.
为什么要去掉:不去掉的话,表示不会执行 finisher()方法.
public static<T,A,R,RR> Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream, Function<R,RR> finisher) { Set<Collector.Characteristics> characteristics = downstream.characteristics(); if (characteristics.contains(Collector.Characteristics.IDENTITY_FINISH)) { if (characteristics.size() == 1) characteristics = Collectors.CH_NOID; else { characteristics = EnumSet.copyOf(characteristics); characteristics.remove(Collector.Characteristics.IDENTITY_FINISH); characteristics = Collections.unmodifiableSet(characteristics); } } return new CollectorImpl<>(downstream.supplier(), downstream.accumulator(), downstream.combiner(), downstream.finisher().andThen(finisher), characteristics); }counting() 计算.
public static <T> Collector<T, ?, Long> counting() { return reducing(0L, e -> 1L, Long::sum); }minBy()
public static <T> Collector<T, ?, Optional<T>> minBy(Comparator<? super T> comparator) { return reducing(BinaryOperator.minBy(comparator)); }maxBy()
public static <T> Collector<T, ?, Optional<T>> maxBy(Comparator<? super T> comparator) { return reducing(BinaryOperator.maxBy(comparator)); }
summingInt(),Long(),Double
为什么要用一个 int[1]? 最后还要返回一个数组中的单个数组呢?直接用一个数组行不行.