list并行流parallel的使用,Collectors进行分组分区,自定义Collector的使用方式

本文介绍了如何使用Java Stream API的并行流(parallelStream)进行数据处理,包括过滤、映射、分组和分区,并展示了如何自定义Collector实现定制化的数据收集。同时,详细讲解了如何使用`maxBy`和`minBy`计算最高分和最低分,以及统计基本统计信息。

list并行流parallel的使用,Collectors进行分组分区

	public static void main(String[] args) {
		Student s1 = new Student("zhangsna",90);
		Student s2 = new Student("wang",45);
		Student s3 = new Student("zhaosl",50);
		Student s4 = new Student("zhaosl",50);
		Student s5 = new Student("xx",50);
		
		List<Student> list = Arrays.asList(s1,s2,s3,s4,s5);
		//通过filter以对象中的一个属性作为条件过滤
		//找出分数大于60的学生对象
		list.stream().filter(s -> s.getScore() > 60).collect(Collectors.toList()).forEach(System.out::println);  //zhangsna 90
		//找出分数大于60的分数
		list.stream().map(s -> s.getScore()).filter(s -> s > 60).collect(Collectors.toList()).forEach(System.out::println);  //90
		
		//parallelStream并行流 与串行流向对sequential相对 当使用并行流parallel时程序会根据cpu核数算出一个默认启用的线程数,开启多个线程并行处理数据
		//mapToInt mapToLong mapToDouble为处理对应类型的特定方法,使得处理对应数据时减少拆装箱的损耗
		//使用并行流计算最后得到数组
		int[] arr2 = list.parallelStream().mapToInt(s -> s.getScore()).filter(s -> s < 60).toArray();
		//使用并行流计算最后得到集合
		List<Integer> scoreList = list.parallelStream().mapToInt(s -> s.getScore()).filter(s -> s < 60).boxed().collect(Collectors.toList());
		
		//使用Collectors获取最高分数和最低分数的学生对象
		list.stream().collect(Collectors.maxBy(Comparator.comparingInt(Student::getScore))).ifPresent(System.out::println); //zhangsna 90
		list.stream().collect(Collectors.minBy(Comparator.comparingInt(Student::getScore))).ifPresent(System.out::println); //wang 45
		
		//计算该集合中的score常规统计的基本信息
		IntSummaryStatistics iss = list.stream().collect(Collectors.summarizingInt(s -> s.getScore()));
		System.out.println(iss); //IntSummaryStatistics{count=5, sum=285, min=45, average=57.000000, max=90}
		
		System.out.println("-------------------分组groupingBy与分区partitioningBy-----------------");
		//分组与多级分组
		//groupingBy 类似与 sql中的group by
		//以姓名为分组条件将集合分组
		Map<String, List<Student>> group = list.stream().collect(Collectors.groupingBy(Student::getName));
		System.out.println(group); //{xx=[xx 50], zhaosl=[zhaosl 50, zhaosl 50], wang=[wang 45], zhangsna=[zhangsna 90]}
		
		//以分数大于等于60为分区条件进行分区
		Map<Boolean, List<Student>> partition = list.stream().collect(Collectors.partitioningBy(s -> s.getScore() >= 60));
		System.out.println(partition);  //{false=[wang 45, zhaosl 50, zhaosl 50, xx 50], true=[zhangsna 90]}
		
		//接口支持多级分区分组
		//先以分数大于等于60进行分区,再按姓名进行分组
		Map<Boolean, Map<String, List<Student>>> partitionThenGroup =list.stream().collect(Collectors.partitioningBy(s ->s.getScore() >60,Collectors.groupingBy(Student::getName)));
		System.out.println(partitionThenGroup); //{false={xx=[xx 50], zhaosl=[zhaosl 50, zhaosl 50], wang=[wang 45]}, true={zhangsna=[zhangsna 90]}}
		
		//分区后统计各区数据
		Map<Boolean, IntSummaryStatistics> partitionThenPartition = list.stream().collect(Collectors.partitioningBy(s -> s.getScore() > 80,Collectors.summarizingInt(Student::getScore)));
		System.out.println(partitionThenPartition); //{false=IntSummaryStatistics{count=4, sum=195, min=45, average=48.750000, max=50}, true=IntSummaryStatistics{count=1, sum=90, min=90, average=90.000000, max=90}}
}

自定义收集器Collector

import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Set;
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接口
public class MyCollector<T> implements Collector<T, Set<T>, Set<T>> {

	//实现supplier接口,该接口为收集器提供一个容器
	@Override
	public Supplier<Set<T>> supplier() {
//		return () -> new HashSet<T>();
		return HashSet<T>::new;
	}

	//实现accumulator接口,该接口提供一个向容器添加元素的方法
	@Override
	public BiConsumer<Set<T>, T> accumulator() {
		return (set,item) -> set.add(item);
	}

	//实现combiner接口,该接口在并行流时提供一个向容器添加另一个容器的方法
	@Override
	public BinaryOperator<Set<T>> combiner() {
		return (set1, set2) -> {
			set1.addAll(set2);
			return set1;
		};
	}

	//实现finisher接口,该接口提供一个方法在结束时可以对容器进行处理
	@Override
	public Function<Set<T>, Set<T>> finisher() {
		return set -> set;
	}

	//characteristics接口中声明收集器的特性
	//Characteristics.IDENTITY_FINISH 忽略finisher接口 当选用此参数时将不会执行finisher()
	//Characteristics.UNORDERED 无序的表示该收集器可以收集一个无序的集合
	//Characteristics.CONCURRENT 表示该收集器容器是一个线程安全的容器,在使用CONCURRENT后选用并行流时,将不会生成多个容器再整合的模式而是多个线程操作一个容器
	@Override
	public Set<Characteristics> characteristics() {
		return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH,Characteristics.UNORDERED));
	}

}
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
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;

public class MyCollector2<T> implements Collector<T, Set<T>, Map<T,T>> {

	@Override
	public Supplier<Set<T>> supplier() {
//		return () -> new HashSet<T>();
		return HashSet<T>::new;
	}

	@Override
	public BiConsumer<Set<T>, T> accumulator() {
		return (set,item) -> set.add(item);
	}

	@Override
	public BinaryOperator<Set<T>> combiner() {
		return (set1, set2) -> {
			set1.addAll(set2);
			return set1;
		};
	}

	//使用自定义收集器的finisher方法重写,将结束后的结果整合成一个map类
	@Override
	public Function<Set<T>, Map<T,T>> finisher() {
		Map<T,T> map = new HashMap<>();
		return set -> {
			set.forEach(t -> {
				map.put(t, t);
			});
			return map;
		};
	}

	@Override
	public Set<Characteristics> characteristics() {
		return Collections.unmodifiableSet(EnumSet.of(Characteristics.UNORDERED));
	}

}
	public static void main(String[] args) {
		Student s1 = new Student("zhangsna",90);
		Student s2 = new Student("wang",45);
		Student s3 = new Student("zhaosl",50);
		Student s4 = new Student("zhaosl",50);
		Student s5 = new Student("xx",50);
		
		List<Student> list = Arrays.asList(s1,s2,s3,s4,s5);

		//自定义收集器
		MyCollector<Student> myCollector = new MyCollector<>();
		
		Set<Student> set = list.stream().filter(s -> s.getScore() < 60).collect(myCollector);
		set.forEach(System.out::println); //zhaosl 50  zhaosl 50  wang 45  xx 50
		
		//自定义一个收集器将结果转换为map类型
		MyCollector2<String> myCollector2 = new MyCollector2<>();
		List<String> list1 = Arrays.asList("a","b","c");
		Map<String,String> map = list1.stream().collect(myCollector2);
		System.out.println(map); //{a=a, b=b, c=c}
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值