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

1100

被折叠的 条评论
为什么被折叠?



