添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
首发于 java基础

stream中lambda的使用 理解 怎么举一反三 stream里的group by的使用

参考: JDK8对List进行分组操作(stream的groupby)

一直以来写lambda的时候都是大概知道了应该传什么数据进里面,不知道的都是直接百度就知道了,感觉好像有些缺少了什么。

何柄融:lambda总结学习理解 函数式接口 方法引用 lambda底层原理 然后复习了一波lambda的基础知识,回忆起它的本质还是传一个未来的运行过程到函数里,然后等函数里面自己去调用。

然后最近看stream分组的时候,感觉好像有些不是很理解.

然后

collect(Collectors.groupingBy(User: :getEdu));

这个就是类似

select * from table where edu='xxx';

这样处理的一个map数据,key是xxx,结果是list里装着对象。 这个应该是最原始的了。


collect(Collectors.groupingBy(User: :getEdu, //第二个参数对Map的value进行处理(映射) Collectors.mapping(User: :getId, Collectors.toList())));

这个是假如你需要的最终结果不是对象,那么就可以在后面加上mapping映射成需要的某个字段的list. 这里由于 collect(Collectors.groupingBy(User: :getEdu)); 返回结果是map对象,出来后不方便进行数据处理,所以直接在里面进行数据映射,直接获取每个对象list里面的id属性,然后变成了id的分组,相当于

select id from table where edu='xxx';


然后我们经常使用的,比如分组求和的

collect(Collectors.groupingBy(User: :getEdu,Collectors.summingDouble(User: :getPrice)));

这个就是等价于

select sum(price) from table group by edu


还有分组计数,也就是统计这个类型的数据有多少个

sql对应就是 select count(*) from table group by edu

对应的代码就是

collect(Collectors.groupingBy(User: :getEdu,
//获取count数量
Collectors.counting()));

貌似不支持having 之类的条件过滤了。


然后就是分组求最大值,这样返回的就不是对象,也不是optional,而是一个值了,所以这里需要自己控制一下最后的转化。

Collector<User, ?, Optional<User>> reducing = Collectors.reducing(BinaryOperator.maxBy(byHeight));

Map<String, Integer> collect4 = users.stream().collect(Collectors.groupingBy(User::getUserName, Collectors.collectingAndThen(reducing, (a) -> a.get().getSchoolId())));

这里注意一下流为空的情况。



Collectors.reducing 就是用于从流中计算某个值的通用机制,其最简单的形式将接受一个二元函数,并从前两个元素开始持续应用它。如果该函数是求和函数,那么就很容易了。

a.stream.reduce((x,y)->x+y) 然后返回一个optional,当流为空,也就返回为空啦,所以使用optional,可以设置默认值。




主要是理解好,stream方法的输入,输出,操作方式是啥,然后会怎么影响到外面的传参

我现在觉得吧,还是要理解好函数式接口,理解它就是一个控制入参,出参,操作方式的东西,理解里面是如何使用泛型进行控制的,然后就可以理解那些stream里面的各种入参,出参了。比如

public static <T, K, D, A, M extends Map<K, D>>
Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier,
Supplier<M> mapFactory,
Collector<? super T, A, D> downstream)

理解stream里面的一些概念,比如下流收集器之类的,然后就看看方法上的注释

Map<City, Set<String>> namesByCity = people.stream().collect(groupingBy(Person::getCity,
mapping(Person::getLastName, toSet())));

groupingBy (classifier, HashMap::new, downstream)

注意里面传个map的new,就是去定义具体的数据存储格式,比如返回的是map,具体是什么map就是根据这个mapproxy来构建的。 后面感觉要进阶的话,还是去看每个方法的底层实现吧,多看看,然后多debug,理解里面的运行原理,这样下次才能快速上手。

主要还是用得比较少,哈哈哈,在流和集合中得下意识去用一下。

发布于 2021-03-17 21:26

文章被以下专栏收录