jdk1.8收集器Collector中的枚举特性

import com.sun.javafx.collections.UnmodifiableObservableMap;

import javax.print.attribute.UnmodifiableSetException;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;

import static java.util.stream.Collector.Characteristics.CONCURRENT;
import static java.util.stream.Collector.Characteristics.IDENTITY_FINISH;
import static java.util.stream.Collector.Characteristics.UNORDERED;

/**
 * 收集器:可变容器,对于目标流的动作
 * 1.输入 Set<String>
 * 2.输出 Map<String,String>
 * 3.示例输入:["hello","world","hello world"]
 * 4.示例输出:[{hello,hello},{world,world},{hello world,hello world}]
 * 5.T,Set<T>,Map<T,T> ---- T(流中元素类型), A(中间结果容器类型), R(返回结果类型)
 * 6.枚举特性IDENTITY_FINISH , UNORDERED ,CONCURRENT
 * @ClassName MySetCollector
 * @Author kate
 */
public class MySetCollector<T> implements Collector<T,Set<T>,Map<T,T>> {

    /**
     *  A a1 = supplier.get();
     *  *     accumulator.accept(a1, t1);
     *  *     accumulator.accept(a1, t2);
     *  *     R r1 = finisher.apply(a1);  // result without splitting
     *  *
     *  *     A a2 = supplier.get();
     *  *     accumulator.accept(a2, t1);
     *  *     A a3 = supplier.get();
     *  *     accumulator.accept(a3, t2);
     *  *     R r2 = finisher.apply(combiner.apply(a2, a3));  // result with splitting
     * @return
     */
    @Override
    public Supplier<Set<T>> supplier() {
        System.out.println("supplier ---->");
       // return HashSet<T>::new;
        return () -> {
            System.out.println(" ---- ---- ");
           // System.out.println("串行流 supplier调用1次 ---->");
           // System.out.println("并行流 supplier调用线程次数个 生成CPU核心数的线程,itel超线程1变2核,4变8核 ---->");
            return new HashSet<T>();
        };
    }

    @Override
    public BiConsumer<Set<T>, T> accumulator() {
        System.out.println("accumulator ---->");
        return (set,item) -> {
            System.out.println("accumulator ---->" +set+" --->" + Thread.currentThread().getName()); //线程名
            set.add(item);
        };
    }

    /**
     * 在并行情况下,且收集器本身没有CONCURRENT特性时会被调用,有不被调用
     * @return
     */
    @Override
    public BinaryOperator<Set<T>> combiner() {
        System.out.println("combiner ---->");
        return (set1,set2) -> {
            // System.out.println("set1 ---->" + set1); 证明是否被调用
            // System.out.println("set2 ---->" + set2);
            set1.addAll(set2);
            return set1;
        };
    }

    @Override
    public Function<Set<T>, Map<T, T>> finisher() {
        System.out.println("finisher ---->");
        //Set<T> 转换成: Map<T, T>
        return set -> {
            Map<T, T> map = new HashMap<>();
            set.stream().forEach(item -> map.put(item,item));
            return map;
        };
    }

    @Override
    public Set<Characteristics> characteristics() {
        System.out.println("characteristics ---->");
        //IDENTITY_FINISH 完成器函数就是IDENTITY函数,A到R的类型转换是成功的,finisher()不执行,对于此例T,R类型不同,故会报错
        //UNORDERED 无序的
        //** CONCURRENT 并行的,多个线程会同时操作同一个结果容器 Collections.unmodifiableSet(EnumSet.of(UNORDERED,CONCURRENT));
        //** 加CONCURRENT特性会不定频率的抛异常,主要是加 System.out.println("accumulator ---->" +set+" --->" + Thread.currentThread().getName());

        //异常原因:多个线程操作一个结果容器,并发修改,一个线程去修改一个集合,另一个线程正在遍历迭代这个集合时,没有并发时则没有异常
        //解决:并行情况下不要修改一个结果容器时同时遍历它
        return  Collections.unmodifiableSet(EnumSet.of(UNORDERED));
    }

    public static void main(String[] args){
        List<String> list = Arrays.asList("hello","world","hello world","hello");
        //串行流1.stream() ; 2.stream().sequential() ;
       // Map<String,String> map = list.stream().collect(new MySetCollector2<>());

        //parallelStream 多个线程操作多个结果容器(不加CONCURRENT)
        //加CONCURRENT多个线程操作一个结果容器,则不需要再合并,合并会报错

        //并行流1.parallelStream() ; 2.stream().parallel()
        Map<String,String> map = list.parallelStream().collect(new MySetCollector2<>());

        //parallel().sequential().parallel().sequential() 串联,看最后一个,其他无效

        System.out.println("map --> " + map);
        //finisher没调用,中间结果个返回一样时可不实现finisher(),不用编写抛异常就可以
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值