java 自定义 operator_java8 自定义Collector
package com.lgx.jdk8.part02;
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;
/**
* 自定义Collector,定义一个Set收集器
*/
public class Test13MySetCollector{
public static void main(String[] args) {
List list = Arrays.asList("hello", "world", "hello", "welcome");
Set set = list.stream().collect(new MySetCollector<>());
System.out.println("set = " + set);
System.out.println("========================");
List list2 = Arrays.asList("hello", "world", "hello", "welcome", "a", "b", "c", "d");
Set set2 = new HashSet<>();
set2.addAll(list2);
System.out.println("set2 = " + set2);
//如果parallel和sequential写多个,以最后一个为准,因为在实现中就是以一个boolean来判断的
for (int i = 0; i < 1; i++) {//执行100次验证并行,加这个参数CONCURRENT报错问题
//Map map = set2.stream().collect(new MyMapCollector<>()); //串行
//Map map = set2.parallelStream().collect(new MyMapCollector<>()); //并行
Map map = set2.stream().sequential().collect(new MyMapCollector<>()); //串行
//Map map = set2.stream().parallel().collect(new MyMapCollector<>()); //并行
System.out.println("map = " + map);
}
System.out.println("可运行线程数=总cpu-被占用的cpu = " + Runtime.getRuntime().availableProcessors());
}
}
//自定义收集器,输入时Set,输出是Set
class MySetCollector implements Collector, Set> {
//创建一个新的容器
@Override
public Supplier> supplier() {
System.out.println("MySetCollector supplier invoked");
return HashSet::new;
}
//累加器:添加一个元素到容器
@Override
public BiConsumer, T> accumulator() {
System.out.println("MySetCollector accumulator invoked");
//return HashSet::add;//这里不能给一个具体的Set,因为supplier方法可能返回的是TreeSet,不一定是HashSet
return Set::add;
}
//把并行流多个结果合并
@Override
public BinaryOperator> combiner() {
System.out.println("MySetCollector combiner invoked");
return (set1, set2) -> {
set1.addAll(set2);
return set1;
};
}
//完成器:合并完返回最终结果
@Override
public Function, Set> finisher() {
System.out.println("MySetCollector finisher invoked");
//return t -> t;
return Function.identity();//与上面那个等价
//throw new UnsupportedOperationException();
}
//返回一个集合,标识这个集合的诸多特性
/**
* Characteristics有3个值:
* CONCURRENT:表示可以并行收集
* UNORDERED:元素不保证顺序的
* IDENTITY_FINISH:表示会执行一个强制类型转换,会调用finisher()方法
*/
@Override
public Set characteristics() {
System.out.println("MySetCollector characteristics invoked");
return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH, Characteristics.UNORDERED));
}
}
//自定义收集器,输入时Set,输出是Map
class MyMapCollector implements Collector, Map> {
//创建一个新的容器
@Override
public Supplier> supplier() {
System.out.println("MyMapCollector supplier invoked");
//return HashSet::new;
return () -> {
System.out.println("***************");//串行这里只执行一次,并行这里执行多次
return new HashSet();
};
}
//累加器:添加一个元素到容器
@Override
public BiConsumer, T> accumulator() {
System.out.println("MyMapCollector accumulator invoked");
//return Set::add;
return (set, item) -> {
System.out.println("MyMapCollector accumulator set = " + set + " " + Thread.currentThread().getName());
//报错在于这里调用(打印)了set,和下面的代码产生了一边修改一边迭代,删掉这个打印就好了
set.add(item);
};
}
//把并行流多个结果合并
@Override
public BinaryOperator> combiner() {
System.out.println("MyMapCollector combiner invoked");
return (set1, set2) -> {
set1.addAll(set2);
System.out.println("MyMapCollector combiner set1 = " + set1 + " set2 = " + set2);
return set1;
};
}
//完成器:合并完返回最终结果
@Override
public Function, Map> finisher() {
System.out.println("MyMapCollector finisher invoked");
return set -> {
Map map = new HashMap();
set.stream().forEach(item -> map.put(item, item));
return map;
};
}
//返回一个集合,标识这个集合的诸多特性
@Override
public Set characteristics() {
System.out.println("MyMapCollector characteristics invoked");
//return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH));//运行会报错,因为这样会执行强制类型转换,而事实上无法将一个Set强制转换成Map
/**
* Characteristics.CONCURRENT:
* 如果上面调用parallelStream,不管有没有这个属性都是并行
* 不加这个属性,是多个线程操作多个结果容器,combiner也会调用多次
* 加了这个属性,是多个线程操作一个结果容器,combiner也无需调用了
*/
return Collections.unmodifiableSet(EnumSet.of(Characteristics.UNORDERED));//合并方法执行多次
//return Collections.unmodifiableSet(EnumSet.of(Characteristics.UNORDERED, Characteristics.CONCURRENT));//合并方法不会执行,多次运行该示例可能抛出异常ConcurrentModificationException
/**
* ConcurrentModificationException:并发修改异常,一个线程修改在一个集合,另一个集合在迭代这个集合,就会报出这个异常
* 不加CONCURRENT,多个容器,也就互不干扰了;加了就一个容器,就会出现这个问题
*/
}
}
java 自定义 operator_java8 自定义Collector相关推荐
- java 8流自定义收集器_Java 8编写自定义收集器简介
java 8流自定义收集器 Java 8引入了收集器的概念. 大多数时候,我们几乎不使用Collectors类中的工厂方法,例如collect(toList()) , toSet()或其他更有趣的方法 ...
- 【Java 注解】自定义注解 ( 使用注解实现简单测试框架 )
文章目录 一.定义注解 二.使用注解 三.解析注解 在 [Java 注解]自定义注解 ( 注解属性定义与赋值 ) 博客中讲解了 注解属性 ; 在 [Java 注解]自定义注解 ( 元注解 ) 博客中讲 ...
- 【Java 注解】自定义注解 ( 注解解析 )
文章目录 一.定义注解 二.使用注解 三.解析注解 四.通过注解对象获取注解属性的原理 在 [Java 注解]自定义注解 ( 注解属性定义与赋值 ) 博客中讲解了 注解属性 ; 在 [Java 注解] ...
- centos 开机启动java_Centos 7将java jar包自定义开机启动服务
Centos 7将java jar包自定义开机启动服务 1. 先上 jar包的启动脚本 vim service.sh #!/bin/bash # 需要变更的参数 # 先查看java绝对路径:which ...
- java闪屏怎么制作,Java Swing创建自定义闪屏:在闪屏下画进度条(一)
Java Swing创建自定义闪屏:在闪屏上画进度条(一) 由于本人十分热爱Java Swing,所以平时闲暇之余总是喜欢极尽所能去搜藏一些自认为比较"酷"的Swing代码来研究揣 ...
- Java针对ArrayList自定义排序的2种实现方法
这篇文章主要介绍了Java针对ArrayList自定义排序的2种实现方法,结合实例形式总结分析了Java操作ArrayList自定义排序的原理与相关实现技巧,下面就和动力节点java学院小编一起来看看 ...
- java android长连接_基于Java Socket的自定义协议,实现Android与服务器的长连接(一)...
一.基础知识准备 在正式给大家介绍自定义协议之前,我们先对网络传输和协议解析的相关知识点做一个基本的介绍,尽管这些知识点我们在学校里学过,但难免会有所遗忘,这里先做一个简单的介绍,以便对后文的内容理解 ...
- java调用kettle自定义kettle.properties配置文件路径
java调用kettle自定义kettle.properties配置文件路径 默认路径 java调用kettle的jar包时,在初始化环境的时候,会在指定路径创建并加载kettle的kettle.pr ...
- java反射实现自定义json转对象方法-忽略字段大小写、字段个数
java反射实现自定义json转对象方法-忽略字段大小写.字段个数 开发过程中经常会遇到json转对象,可以使用FastJson或者Gson自带的工具类进行转换,但当遇到json与对象属性名称大小写不 ...
最新文章
- usermod命令的一些用法详解
- WCF单元测试遇到的问题
- LIS(基于贪心的O(NlogN)解法)
- 应届生拿到offer之后的流程_【经验】我是如何一步步拿到拼多多amp;京东amp;艺龙等多个产品offer的...
- angularjs1.x版本,父子组件之间的双向绑定
- 销售易CRM:提高管理效率需做好业绩预测
- html弹出框交互,HTML5/SVG模态窗口(对话框)交互动画
- 品牌类软文经典案例分享,深刻了解软文营销的“魅力”
- VOSviewer软件研究热点分析
- Python -- 扫描局域网活跃IP
- HTML布局方式Flex属性详解
- 初始vue脚手架的项目文件中mian.js文件
- ADS1256,引起了通信丢失
- 聊聊电商系统中红包活动设计
- 服务器内置usb能否修改为外置,台式机内置的DVD刻录机可以改成外置的USB接口吗?...
- layer的anim动画
- CMMI有哪几个级别,每个级别有哪些其特征
- windows SDK模拟游戏钢琴的实现(一)
- 【牛客网面经整理】20200831小米一面
- opencv计算机视觉_opencv是计算机视觉的至尊工具
热门文章
- mongodb数据库扩展名_MongoDB学习笔记:MongoDB 数据库的命名、设计规范
- Windows最经典应用大变脸:学生爽翻!
- OpenWrt启动过程分析+添加自启动脚本【转】
- 从尼古拉斯·泽卡斯开始学习
- java并发的艺术-读书笔记-第八章常用的并发工具类
- Oracle获取最近执行的SQL语句
- robots.txt网站爬虫文件设置
- 用jquery mobile 实现幻灯片效果
- DrawerLayout + Toolbar + ViewPager
- $emit传递多个参数_Go语言参数传递方式