Collector都搞不清楚,写什么Java,一张图搞定!

简介: 最近一段时间比较忙,也不知道都在做些什么。五一期间本来打算写一篇的,但是一直有各种事情拖着也没写下来。今天继续是计划内的一篇文章collector。

最近一段时间比较忙,也不知道都在做些什么。五一期间本来打算写一篇的,但是一直有各种事情拖着也没写下来。今天继续是计划内的一篇文章collector。


1、用来做什么的?


collectors直接翻译就是收集器。主要的作用是就是将流中的数据进行收集整理。collectors主要还是配合stream来使用。平常的话也不会用到。


2、都有哪些用法?


Collectors可以帮我们完成的事情,例如:分组、排序(支持多字段排序)、最大值、最小值、平均值,简单的来说,以前我们在数据上面用sql 去完成的聚合相关的操作,Collectors 都可以完成。可以参照stream那一篇。


3、源码怎么实现的?


Collectors到底是怎么实现的呢?现在来看一下源码,一起学习一下。


先看一下collect需要传入的参数都有哪些。


a676daf95f50469db0e0609f36068a74~tplv-k3u1fbpfcp-zoom-in-crop-mark_1304_0_0_0.webp.jpg


可以看到有两种实现


一种实现就是传入三个函数。


<R> R collect(Supplier<R> supplier,
BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner);
复制代码


另外一种实现就是传入一个collector。其实没有本质上的区别。


list.stream().collect(Collectors.toList())
复制代码


先看看最简单的Collectors.toSet()实现。


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);
    }
复制代码


从上面代码可以看到toSet返回了一个CollectorImpl,CollectorImpl实现和上面的三个函数差不多。只有一个参数不一样。


CollectorImpl(Supplier<A> supplier,
   BiConsumer<A, T> accumulator,
    BinaryOperator<A> combiner,
    Set<Characteristics> characteristics) {
     this(supplier, accumulator, combiner, castingIdentity(), characteristics   }
复制代码


下面开始理解这个三个函数到底都在做什么?


Supplier<A> supplier, supplier是主要创建一个新的对象返回。一般用来返回一个容器对象。


BiConsumer<A, T> accumulator, 主要是用来累加合并,将新的T和A进行融合。一般来说T放入a的集合中。


BinaryOperator<A> combiner,主要是用来对多线程的时候进行组装。


Set<Characteristics> characteristics 最后一个参数主要是描述集合的特性,需要做什么样的操作。等下会有介绍。


具体流程是什么样的我们自己来实现一下


List<String> list = Lists.newArrayList();
      list.add("香菜");
      list.add("聊游戏");
      Supplier<Set<String>> supplier = ()-> new HashSet<>();
      BiConsumer<Set<String>, String> accumulator = (set, s) -> set.add(s);
      BiConsumer<Set<String>, Set<String>> combiner = (left,right)->{left.addAll(right);};
      Set<String> collect = list.stream().parallel().collect(supplier, accumulator, combiner);
      System.out.println(collect);
复制代码


我们到底做了什么?


R result = supplier.get();
for (T element : this stream)
        accumulator.accept(result, element);
return result;
复制代码


多线程的情况下就像下面这张图。


84f194bb2ff44fdb8a4fd401cb9b0b41~tplv-k3u1fbpfcp-zoom-in-crop-mark_1304_0_0_0.webp.jpg


而collect中只有一个参数,那就是Collector对象,java.util.stream.Collector 这是一个接口,其功能是将流处理的结果,汇聚处理成最终的一个可变对象(容器)。 这个接口有5个方法:


  1. Supplier supplier(); 创建一个结果容器


  1. BiConsumer accumulator(); 将元素合并到结果容器中


  1. BinaryOperator combiner(); 将两个结果容器合并


  1. Function finisher(); 最终操作


  1. Set characteristics();返回一个固定的特征集合


特征集合:


/**当前Collector支持并发,一般情况下UNORDERED也会一起放在characteristics中*/
      CONCURRENT,
      /** 当前Collector对操作元素是不会关心顺序的的 */
      UNORDERED,
      /**当前Collector没有Finisher*/
      IDENTITY_FINISH
复制代码



c32051d404614a86818f249dbc3745d3~tplv-k3u1fbpfcp-zoom-in-crop-mark_1304_0_0_0.webp.jpg


看了源码应该了解是怎么回事了,具体的实现可以参照Collector 的实现,so easy。


4、总结


Collectors一个常用的collector工厂,这个工厂就是collect中常用的收集方式的实现。记住最重要的那张图,一切就迎刃而解了。


目录
相关文章
|
7月前
|
Java API 图形学
Java代码可以做出动图
Java代码可以做出动图
89 1
|
7月前
|
Java C语言
用Java(C语言也可以看)实现冒泡排序和折半查找(详细过程图)+逆序数组
用Java(C语言也可以看)实现冒泡排序和折半查找(详细过程图)+逆序数组
76 0
|
6月前
|
存储 算法 Java
Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。
【6月更文挑战第21天】Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。二叉树遍历通过访问根、左、右子节点实现。DFS采用递归遍历图的节点,而BFS利用队列按层次访问。以下是简化的代码片段:[Java代码略]
50 4
|
6月前
|
存储 算法 Java
【经典算法】LeetCode133克隆图(Java/C/Python3实现含注释说明,中等)
【经典算法】LeetCode133克隆图(Java/C/Python3实现含注释说明,中等)
37 2
|
6月前
|
Java
图深度优先、广度优先遍历(java)
图深度优先、广度优先遍历(java)
|
7月前
|
算法 Java
Java必刷入门递归题×5(内附详细递归解析图)
Java必刷入门递归题×5(内附详细递归解析图)
98 1
|
7月前
|
NoSQL Java 关系型数据库
基于java Swing 和 mysql实现的飞机订票系统(源码+数据库+ppt+ER图+流程图+架构说明+论文+运行视频指导)
基于java Swing 和 mysql实现的飞机订票系统(源码+数据库+ppt+ER图+流程图+架构说明+论文+运行视频指导)
749 0
|
7月前
|
NoSQL Java 关系型数据库
基于java swing和mysql实现的学生选课成绩信息管理系统(源码+数据库+ER图文档+运行指导视频)
基于java swing和mysql实现的学生选课成绩信息管理系统(源码+数据库+ER图文档+运行指导视频)
254 0
【零基础学Java】—对象的内存图(八)
【零基础学Java】—对象的内存图(八)
|
存储 Java 索引
[正式学习java②]——数组的基本使用,java内存图与内存分配
[正式学习java②]——数组的基本使用,java内存图与内存分配