Stream流与Lambda表达式(四) 自定义收集器
一、自定义SetCustomCollector收集器
package com.java.design.Stream.CustomCollector;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;/*** @author 陈杨*/// 将List集合转换为Set集合 存放相同元素
public class SetCustomCollector<T> implements Collector<T, Set<T>, Set<T>> {@Overridepublic Supplier<Set<T>> supplier() {System.out.println("supplier invoked!");// return TreeSet::new;return HashSet::new;}@Overridepublic BiConsumer<Set<T>, T> accumulator() {System.out.println("accumulator invoked!");return Set<T>::add;}@Overridepublic BinaryOperator<Set<T>> combiner() {System.out.println("combiner invoked!");return (first, last) -> {first.addAll(last);return first;};}@Overridepublic Function<Set<T>, Set<T>> finisher() {System.out.println("finisher invoked!");return Function.identity();}@Overridepublic Set<Characteristics> characteristics() {System.out.println("characteristics invoked!");return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH, Characteristics.UNORDERED));// return Collections.unmodifiableSet(EnumSet.of(Characteristics.UNORDERED));}}
二、自定义StudentCustomCollector收集器
package com.java.design.Stream.CustomCollector;import com.java.design.java8.entity.Student;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;/*** @author 陈杨*/// 将学生对象 按照HashMap<Integer,Student> 存放 sid student
public class StudentCustomCollector implements Collector<Student, List<Student>, Map<Integer, Student>> {@Overridepublic Supplier<List<Student>> supplier() {System.out.println("supplier invoked!");return ArrayList::new;}@Overridepublic BiConsumer<List<Student>, Student> accumulator() {System.out.println("accumulator invoked!");return (list, student) -> {System.out.println("accumulator:" + Thread.currentThread().getName());list.add(student);};}@Overridepublic BinaryOperator<List<Student>> combiner() {System.out.println("combiner invoked!");return (first, last) -> {first.addAll(last);return first;};}@Overridepublic Function<List<Student>, Map<Integer, Student>> finisher() {System.out.println("finisher invoked!");return list -> {Map<Integer, Student> map = new HashMap<>();list.forEach(student -> map.put(student.getId(), student));return map;};}@Overridepublic Set<Characteristics> characteristics() {System.out.println("Characteristics invoked!");return Collections.unmodifiableSet(EnumSet.of(Characteristics.CONCURRENT));}// Characteristics.IDENTITY_FINISH 从中间容器数据类型 转换为 结果类型 数据类型一致// 若不一致 抛出类型转换异常 finisher对中间容器数据-->结果类型 进行强制类型转换// Characteristics.CONCURRENT 多个线程同时操作同一个容器 --> 并行// Indicates that this collector is <em>concurrent</em>, meaning that// the result container can support the accumulator function being// called concurrently with the same result container from multiple threads.// parallelStream (多线程)并行流 操作 多个结果容器 --> 执行combiner// Characteristics.CONCURRENT + parallelStream 结果容器只有1个 ---> 不执行 combiner// ConcurrentModificationException 并发修改异常// 注意:并行情况下 累加器对结果容器执行单一操作// 不要在累加器返回的函数式接口实例中做额外的操作// 不能打印集合类容 同时向集合里添加新元素// This exception may be thrown by methods that have detected concurrent// modification of an object when such modification is not permissible
}
三、SetCustomCollectorTest测试
package com.java.design.java8.Stream.CustomCollector;import com.java.design.Stream.CustomCollector.SetCustomCollector;
import com.java.design.java8.entity.Student;
import com.java.design.java8.entity.Students;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;import java.util.List;
import java.util.Set;/*** @author 陈杨*/@SpringBootTest
@RunWith(SpringRunner.class)
public class SetCustomCollectorTest {private List<Student> students;@Beforepublic void init() {students = new Students().init();}@Testpublic void testSetCustomCollector() {Set<Student> set = students.stream().collect(new SetCustomCollector<>());System.out.println(set);}/*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> {@Overridepublic void begin(long size) {state = supplier.get();}@Overridepublic void accept(T t) {accumulator.accept(state, t);}@Overridepublic void combine(ReducingSink other) {state = combiner.apply(state, other.state);}}return new ReduceOp<T, I, ReducingSink>(StreamShape.REFERENCE) {@Overridepublic ReducingSink makeSink() {return new ReducingSink();}@Overridepublic int getOpFlags() {return collector.characteristics().contains(Collector.Characteristics.UNORDERED)? StreamOpFlag.NOT_ORDERED: 0;}};}*//*public final <R, A> R collect(Collector<? super P_OUT, A, R> collector) {A container;if (isParallel()&& (collector.characteristics().contains(Collector.Characteristics.CONCURRENT))&& (!isOrdered() || collector.characteristics().contains(Collector.Characteristics.UNORDERED))) {container = collector.supplier().get();BiConsumer<A, ? super P_OUT> accumulator = collector.accumulator();forEach(u -> accumulator.accept(container, u));}else {container = evaluate(ReduceOps.makeRef(collector));}return collector.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)? (R) container: collector.finisher().apply(container);}*/// 执行流程 方法调用顺序// container = evaluate(ReduceOps.makeRef(collector));// Supplier<I> supplier = Objects.requireNonNull(collector).supplier();// BiConsumer<I, ? super T> accumulator = collector.accumulator();// BinaryOperator<I> combiner = collector.combiner();// return collector.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)是否有序// return collector.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)是否包含IDENTITY_FINISH// ? (R) container 注意强制类型转换 (中间类型 与 返回结果类型)// 注意强制类型转换/*CollectorImpl(Supplier<A> supplier,BiConsumer<A, T> accumulator,BinaryOperator<A> combiner,Set<Characteristics> characteristics) {this(supplier, accumulator, combiner, castingIdentity(), characteristics);}@SuppressWarnings("unchecked")private static <I, R> Function<I, R> castingIdentity() {return i -> (R) i;}*/// EnumSet.of(Characteristics.IDENTITY_FINISH, Characteristics.UNORDERED)// 包含 IDENTITY_FINISH 打印结果// supplier invoked!// accumulator invoked!// combiner invoked!// characteristics invoked!// characteristics invoked!// Set<Student>集合对象// EnumSet.of(Characteristics.UNORDERED)// 不包含 IDENTITY_FINISH 打印结果// supplier invoked!// accumulator invoked!// combiner invoked!// characteristics invoked!// characteristics invoked!// finisher invoked!// Set<Student>集合对象}
四、StudentCustomCollectorTest测试
package com.java.design.java8.Stream.CustomCollector;import com.java.design.Stream.CustomCollector.StudentCustomCollector;
import com.java.design.java8.entity.Student;
import com.java.design.java8.entity.Students;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;import java.util.List;
import java.util.Map;/*** @author 陈杨*/@SpringBootTest
@RunWith(SpringRunner.class)
public class StudentCustomCollectorTest {private List<Student> students;@Beforepublic void init() {students = new Students().init();}@Testpublic void testStudentCustomCollectorTest() {System.out.println("单线程");Map<Integer, Student> sequentialMap = students.stream().collect(new StudentCustomCollector());System.out.println("串行流执行效果:\n---------------------------------------\n"+sequentialMap);System.out.println("---------------------------------------\n");System.out.println("多线程");Map<Integer, Student> parallelMap = students.parallelStream().collect(new StudentCustomCollector());System.out.println("并行流执行效果:\n---------------------------------------\n"+parallelMap);System.out.println("---------------------------------------\n");}}
五、测试结果
SetCustomCollectorTest测试结果. ____ _ __ _ _/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/ ___)| |_)| | | | | || (_| | ) ) ) )' |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot :: (v2.1.2.RELEASE)2019-02-20 17:14:45.547 INFO 3260 --- [ main] c.j.d.j.S.C.SetCustomCollectorTest : Starting SetCustomCollectorTest on DESKTOP-87RMBG4 with PID 3260 (started by 46250 in E:\IdeaProjects\design)
2019-02-20 17:14:45.548 INFO 3260 --- [ main] c.j.d.j.S.C.SetCustomCollectorTest : No active profile set, falling back to default profiles: default
2019-02-20 17:14:46.055 INFO 3260 --- [ main] c.j.d.j.S.C.SetCustomCollectorTest : Started SetCustomCollectorTest in 0.686 seconds (JVM running for 1.43)
supplier invoked!
accumulator invoked!
combiner invoked!
characteristics invoked!
characteristics invoked!
[Student(id=4, name=Yuuki, sex=Female, age=15, addr=Alfheim Online, salary=9.99999999E8), Student(id=3, name=Sinon, sex=Female, age=16, addr=Gun Gale Online, salary=9.99999999E8), Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8), Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8), Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8)]
StudentCustomCollectorTest测试. ____ _ __ _ _/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/ ___)| |_)| | | | | || (_| | ) ) ) )' |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot :: (v2.1.2.RELEASE)2019-02-20 17:15:52.817 INFO 3292 --- [ main] c.j.d.j.S.C.StudentCustomCollectorTest : Starting StudentCustomCollectorTest on DESKTOP-87RMBG4 with PID 3292 (started by 46250 in E:\IdeaProjects\design)
2019-02-20 17:15:52.818 INFO 3292 --- [ main] c.j.d.j.S.C.StudentCustomCollectorTest : No active profile set, falling back to default profiles: default
2019-02-20 17:15:53.354 INFO 3292 --- [ main] c.j.d.j.S.C.StudentCustomCollectorTest : Started StudentCustomCollectorTest in 0.745 seconds (JVM running for 1.439)
单线程
supplier invoked!
accumulator invoked!
combiner invoked!
Characteristics invoked!
accumulator:main
accumulator:main
accumulator:main
accumulator:main
accumulator:main
Characteristics invoked!
finisher invoked!
串行流执行效果:
---------------------------------------
{1=Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8), 2=Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8), 3=Student(id=3, name=Sinon, sex=Female, age=16, addr=Gun Gale Online, salary=9.99999999E8), 4=Student(id=4, name=Yuuki, sex=Female, age=15, addr=Alfheim Online, salary=9.99999999E8), 5=Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8)}
---------------------------------------多线程
Characteristics invoked!
Characteristics invoked!
supplier invoked!
accumulator invoked!
combiner invoked!
Characteristics invoked!
accumulator:main
accumulator:ForkJoinPool.commonPool-worker-5
accumulator:ForkJoinPool.commonPool-worker-5
accumulator:ForkJoinPool.commonPool-worker-3
accumulator:main
Characteristics invoked!
finisher invoked!
并行流执行效果:
---------------------------------------
{1=Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8), 2=Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8), 3=Student(id=3, name=Sinon, sex=Female, age=16, addr=Gun Gale Online, salary=9.99999999E8), 4=Student(id=4, name=Yuuki, sex=Female, age=15, addr=Alfheim Online, salary=9.99999999E8), 5=Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8)}
---------------------------------------
Stream流与Lambda表达式(四) 自定义收集器相关推荐
- Stream流与Lambda表达式(三) 静态工厂类Collectors
/*** @author 陈杨*/@SpringBootTest @RunWith(SpringRunner.class) public class CollectorsDetail {private ...
- stream流及lambda表达式快速总结
前言: 内容: stream流是对集合迭代器的增强,使得对集合可以进行高效的聚合操作(过滤,排序.统计分组)或者大批量数据操作,stream流中用到了lambda表达式进行高效率代码书写.lambda ...
- Stream流与Lambda表达式(一) 杂谈
一.流 转换为数组.集合 package com.java.design.java8.Stream;import org.junit.Test; import org.junit.runner.Run ...
- Java Stream 流常用方法 lambda 表达式实现交集、并集、差集、去重复并集等
一般的javaList 交.并集采用简单的 removeAll retainAll 等操作,不过这也破坏了原始的javaList对象,采用java8 lambda表达式流操作则可以不影响原始list对 ...
- 使用Java8新特性(stream流、Lambda表达式)实现多个List 的笛卡尔乘积 返回需要的List<JavaBean>
需求分析: 有两个Long类型的集合 : List<Long> tagsIds; List<Long> attributesIds; 现在需要将这两个Long类型的集合进行组合 ...
- Stream流和Lambda表达式遍历HashMap
Map<String,Object> map = new HashMap<>();map.put("name","zhongxu");m ...
- java 8流自定义收集器_Java 8编写自定义收集器简介
java 8流自定义收集器 Java 8引入了收集器的概念. 大多数时候,我们几乎不使用Collectors类中的工厂方法,例如collect(toList()) , toSet()或其他更有趣的方法 ...
- Java8 Stream 自定义收集器Collector
在之前的例子中,我们都是使用Collectors的静态方法提供的CollectorImpl,为接口Collector<T, A, R>的一个实现类,为了自定义我们自己的Collector, ...
- Java 8编写自定义收集器简介
Java 8引入了收集器的概念. 大多数时候,我们几乎不使用Collectors类中的工厂方法,例如collect(toList()) , toSet()或其他更花哨的方法,例如counting()或 ...
最新文章
- 《概率机器人》里程计运动模型gmapping中代码解析
- LeetCode 1027. Longest Arithmetic Sequence--笔试题--C++解法
- NtQueryInformationProcess用法
- 打造万能的Python开发环境
- python实现文件管理系统_Python使用文件操作实现一个XX信息管理系统的示例
- 1284:摘花生《信息学奥赛一本通》
- c语言1000行代码,【图片】【标题党】论我是如何一分钟写1000行代码的【c语言吧】_百度贴吧...
- _Linux内核分析(二)-内核模块简介和简单内核模块实现
- openstack部署(四)--网络配置(Networking)
- 《Linux内核设计与实现》读书笔记(12)--- 内存管理(2)
- android rtc 不能写时间到 rtc 原因分析
- oracle恢复init文件,详解NBU异机恢复ORACLE数据库
- 计算机应用基础教程学什么,[电脑基础知识]计算机应用基础教程学习.ppt
- qqkey获取原理_征途手机版电脑版安装使用教程【安卓+ios电脑版图文攻略】
- 【牛客网】C/C++牛客网专项刷题(04)
- vue幸运大转盘实现
- (十二)简单说一说drop、delete与truncate的区别
- 初学量子力学,读读这本《见微知著》,会豁然开朗
- 17_微信小程序之抖音微视无限滑动视频列表自定义组件编写
- 16个时髦的扁平化设计的 HTML5 CSS3 网站模板
热门文章
- WPF Dispatcher介绍
- 如何优雅地实施持续交付部署
- 一行代码集成带负数的自定义键盘
- Css常用操作——————分类
- “云计算” 保险业发展新动力
- OPM攻击事件后:我们从中学到了什么?
- Oracle PL/SQL Developer集成TFS进行团队脚本文件版本管理
- 【DataGuard】ORA-16014 and ORA-00312 Messages in Alert.log of Physical Standby
- java 鼠标 停止工作原理,java系统级的键盘和鼠标状态
- java date 格式化_3种 Springboot 全局时间格式化方式,别再写重复代码了