设为首页 加入收藏

TOP

Java8 函数式编程探秘(三)
2018-01-30 12:42:56 】 浏览:916
Tags:Java8 函数 编程 探秘
BinaryOperator<List<Integer>> combiner() : 照葫芦画瓢,目前没看出这步是做什么用;直接 return null; 也是OK的。
  • 最终转换器 Function<List<Integer>, List<Integer>> finisher() :在最终转换器中,移除初始设置的两个值 0, 1 。
  • 代码如下:

    /**
     * Created by shuqin on 17/12/5.
     */
    public class FiboCollector implements Collector<Integer, List<Integer>, List<Integer>> {
    
      public Supplier<List<Integer>> supplier() {
        return () -> {
          List<Integer> result = new ArrayList<>();
          result.add(0); result.add(1);
          return result;
        };
      }
    
      @Override
      public BiConsumer<List<Integer>, Integer> accumulator() {
        return (res, num) -> {
          Integer next = res.get(res.size()-1) + res.get(res.size()-2);
          res.add(next);
        };
      }
    
      @Override
      public BinaryOperator<List<Integer>> combiner() {
        return null;
        //return (left, right) -> { left.addAll(right); return left; };
      }
    
      @Override
      public Function<List<Integer>, List<Integer>> finisher() {
        return res -> { res.remove(0); res.remove(1); return res; };
      }
    
      @Override
      public Set<Characteristics> characteristics() {
        return Collections.emptySet();
      }
    
    }
    
    List<Integer> fibo = Arrays.asList(1,2,3,4,5,6,7,8,9,10).stream().collect(new FiboCollector());
    System.out.println(fibo);

    流(Stream)是Java8对函数式编程的重要支撑。大部分函数式工具都围绕Stream展开。

    Stream的接口

    Stream 主要有四类接口:

    • 流到流之间的转换:比如 filter(过滤), map(映射转换), mapTo[Int|Long|Double] (到原子类型流的转换), flatMap(高维结构平铺),flatMapTo[Int|Long|Double], sorted(排序),distinct(不重复值),peek(执行某种操作,流不变,可用于调试),limit(限制到指定元素数量), skip(跳过若干元素) ;
    • 流到终值的转换: 比如 toArray(转为数组),reduce(推导结果),collect(聚合结果),min(最小值), max(最大值), count (元素个数), anyMatch (任一匹配), allMatch(所有都匹配), noneMatch(一个都不匹配), findFirst(选择首元素),findAny(任选一元素) ;
    • 直接遍历: forEach (不保序遍历,比如并行流), forEachOrdered(保序遍历) ;
    • 构造流: empty (构造空流),of (单个元素的流及多元素顺序流),iterate (无限长度的有序顺序流),generate (将数据提供器转换成无限非有序的顺序流), concat (流的连接), Builder (用于构造流的Builder对象)

    除了 Stream 本身自带的生成Stream 的方法,数组和容器及StreamSupport都有转换为流的方法。比如 Arrays.stream , [List|Set|Collection].[stream|parallelStream] , StreamSupport.[int|long|double|]stream;

    流的类型主要有:Reference(对象流), IntStream (int元素流), LongStream (long元素流), Double (double元素流) ,定义在类 StreamShape 中,主要将操作适配于类型系统。

    flatMap 的一个例子见如下所示,将一个二维数组转换为一维数组:

         List<Integer> nums = Arrays.asList(Arrays.asList(1,2,3), Arrays.asList(1,4,9), Arrays.asList(1,8,27))
                                    .stream().flatMap(x -> x.stream()).collect(Collectors.toList());
         System.out.println(nums);

    collector实现

    这里我们仅分析串行是怎么实现的。入口在类 java.util.stream.ReferencePipeline 的 collect 方法:

    container = eva luate(ReduceOps.makeRef(collector));
    return collector.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)
              ? (R) container : collector.finisher().apply(container);

    这里的关键是 ReduceOps.makeRef(collector)。 点进去:

    public static <T, I> TerminalOp<T, I>
        makeRef(Collector<? super T, I, ?> collector) {
            Supplier<I> supplier = Objects.requireNonNull(collector).supplier();
            BiConsumer<I, ? super T> accumulator = collector.accumulator();
            BinaryOperator<I> combiner = collector.combiner();
            class ReducingSink extends Box<I>
                    implements AccumulatingSink<T, I, ReducingSink> {
                @
    首页 上一页 1 2 3 4 5 6 7 下一页 尾页 3/9/9
    】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
    上一篇通向架构师的道路(第六天)之漫.. 下一篇JUnit 源码解析

    最新文章

    热门文章

    Hot 文章

    Python

    C 语言

    C++基础

    大数据基础

    linux编程基础

    C/C++面试题目