学会java中使用Stream流进行数据处理

找不到有用的Stream文章?搜索全是处理数字数组或者字符串数字?实战干货,即贴即用

Collectors类:

Collector接口的实现,它实现了各种有用的缩减、操作,例如将元素累积到集合中、汇总、根据各种条件的元素等


能干什么

  • 排序查找过滤
  • 数据分组
  • 数据分区
  • 数据分组后,对每一个组进行缩减统计
  • ···

JDK给的官方例子!

// 获取所有学生的名字,结果收集为List<String>
List<String> names= people.stream()
    .map(Person::getName)
    .collect(Collectors.toList());

// 获取所有学生的名字,结果收集为TreeSet
Set<String> set = people.stream()
    .map(Person::getName)
    .collect(Collectors.toCollection(TreeSet::new));

// 将元素转换为字符串并连接它们,用逗号分隔
String joined = things.stream()
    .map(Object::toString)
    .collect(Collectors.joining(","));

// 计算员工工资总额
int total = employees.stream()
    .collect(Collectors.summingInt(Employee::getSalary)));

// 按部门分组的员工(上游按部门进行分组;下游不做处理,则是一个员工对象list)
Map<Department, List<Employee>> byDept = employees.stream()
    .collect(Collectors.groupingBy(Employee::getDepartment));

// 按部门计算工资总额(上游按部门进行分组;下游求和int,返回Integer)
Map<Department, Integer> totalByDept = employees.stream()
    .collect( Collectors.groupingBy( 
        Employee::getDepartment,
        Collectors.summingInt(Employee::getSalary)));

// 将学生分为及格和不及格
Map<Boolean, List<Student>> passingFailing = students.stream()
    .collect(Collectors.partitioningBy(s -> {
        s.getGrade() >= PASS_THRESHOLD
    }));

// 计算每个城市居民的最长姓氏(上游按城市分组,下游通过reducing,传入一个比较器返回名字最长的name)
Comparator<String> byLength = Comparator.comparing(String::length);
Map<City, String> longestLastNameByCity = people.stream()
    .collect(groupingBy(
        Person::getCity, 
        reducing(Person::getLastName, BinaryOperator.maxBy(byLength))
    ) );

// 计算每个城市中人们的姓氏集合(上游按城市分组,下游收集LastName并转换为Set)
Map<City, Set<String>> namesByCity = people.stream()
    .collect(groupingBy(
        Person::getCity,
        mapping(Person::getLastName, toSet())
    ));

// 计算每个城市中人们的姓氏集,并按城市名排序(上游按城市分组,下游收集LastName并转换为Set,中间转为TreeMap)
Map<City, Set<String>> namesByCity = people.stream()
    .collect( groupingBy(
        Person::getCity, 
        TreeMap::new,
        mapping(Person::getLastName, toSet())
    ));
ConcurrentMap<City, Set<String>> namesByCity = people.stream()
    .collect(groupingBy(
        Person::getCity, 
        ConcurrentSkipListMap::new,
        mapping(Person::getLastName, toSet())
    ));

// 将学生与他们的平均成绩进行比较
Map<Student, Double> studentToGPA = students.stream()
    .collect(toMap(
        Functions.identity(),
        student -> computeGPA(student)
    ));

// 将唯一标识符映射到学生
Map<String, Student> studentIdToStudent = students.stream()
    .collect(toMap(
        Student::getId,
        Functions.identity()
    ));

// 将名称映射到连接的地址列表
Map<String, String> phoneBook = people.stream()
    .collect(toMap(
        Person::getName,
        Person::getAddress,
        (s, a) -> s + ", " + a))
    );

Collectors静态方法介绍:

  • 转换
// 转换为Collection
toCollection(Supplier<C> collectionFactory);
// 转换为List
toList();
// 转换为Set
toSet();
  • 拼接
// 通过StringBuilder拼接,返回String
joining();

// 指定拼接的 分隔符
joining(CharSequence delimiter);

// 指定拼接的 分隔符 开始 和结尾(类似 mybatis 的 separator=',' open='(' close=')' )
joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix));
  • 映射
mapMerger();

// 将接受类型元素的Collector改编为接受T类型元素的Collector,mapper 应用于输入元素的函数,downstream 接受映射值的收集器
mapping(Function<? super T, ? extends U> mapper,Collector<? super U, A, R> downstream);
  • 数学计算
// 统计元素的数量,如果不存在任何元素,则结果为0
counting();

// 根据给定的比较器 Comparator 生成最小元素
minBy(Comparator<? super T> comparator);

// 根据给定的比较器Comparator生成最大元素
maxBy(Comparator<? super T> comparator);

// 求和:没有元素参与计算,返回0
summingInt(ToIntFunction<? super T> mapper);
summingLong(ToLongFunction<? super T> mapper);
summingDouble(ToDoubleFunction<? super T> mapper);

//求平均:返回double类型或者0.0d;没有元素参与计算,返回0
averagingInt(ToIntFunction<? super T> mapper);
averagingLong(ToLongFunction<? super T> mapper);
averagingDouble(ToDoubleFunction<? super T> mapper);
  • reduce
// 元素缩减:常用于下游的多级约简中使用
reducing(BinaryOperator<T> op);
reducing(T identity, BinaryOperator<T> op);
reducing(U identity, Function<? super T, ? extends U> mapper, BinaryOperator<U> op);
  • 分组,根据分类函数对元素进行分组,返回Map
// 直接分组
groupingBy(Function);
// 分组后,下游可以对 “集合” 执行操作
groupingBy(Function, Collector);
// 分组后,下游可以对 “集合” 执行操作,并且转换为mapFactory
groupingBy(Function, Supplier, Collector);

使用groupingByConcurrent可以提供更好的并行性能
	groupingByConcurrent(Function);
	groupingByConcurrent(Function, Collector);
	groupingByConcurrent(Function, Supplier, Collector);
  • 分区
// 直接分区
partitioningBy(Function);

// 分区后,下游可以对 “集合” 执行操作
partitioningBy(Function, Collector);
  • 手动转为Map,使用map.merge(key,value,function,T)
    映射指定的key和value
toMap(Function, Function);
toMap(Function, Function, BinaryOperator);
toMap(keyMapper, valueMapper, BinaryOperator, Supplier);

// 使用toConcurrentMap可以提供更好的并行性能	
toConcurrentMap();
toConcurrentMap();
toConcurrentMap();
  • 其它
summarizingInt();
summarizingLong();
summarizingDouble();
collectingAndThen();

基本概念:什么是 Stream?

Stream(流)是一个来自数据源的元素队列并支持聚合操作

  • 元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
  • 数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
  • 聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。

和以前的Collection操作不同, Stream操作还有两个基础的特征:

  • Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
  • 内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。

生成流

在 Java 8 中, 集合接口有两个方法来生成流:

  • stream() − 为集合创建串行流。
  • parallelStream() − 为集合创建并行流。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值