Java8新特性Stream使用心得之:groupingBy与partitioningBy

业务开发过程中,经常会需要将集合中的数据进行聚合操作。比如:取出订单集合中有效订单的数据、按照订单类型做分组等等。以前的处理方式会遍历这个集合然后通过业务判断做处理,虽然可用,但远不够高效且笨拙。

为什么需要Stream

Stream是Java8的一大亮点,是对集合对象(Collection)功能的增强,进行聚合操作、批量数据操作。同时借助于Lambda表达式,提高编程效率和可读性。此外,Stream提供了并发模式,可充分使用多核处理器的优势,底层使用fork/join 并行方式来拆分任务和加速处理过程。

什么是Stream流

Stream不保存数据,也不是一种数据结构,更不是集合元素,而是有关算法和计算的,就像Iterator,只是更高级。Stream会隐式的在内部进行遍历,做出对应的数据转换。Stream类比于迭代器(Iterator)去理解,是单向、不可往复、只能遍历一次。
但是,迭代器只能串行化操作,也就是说用迭代器去遍历时,每个item 读完后再读下一个 item。Stream的并行操作依赖于Java7引入的Fork/Join 框架(JSR166y)来拆分任务和加速处理。
list.stream():串行遍历;
list.parallelStream():并行处理;

Stream之groupingBy

groupingBy是都集合进行分组,分组之后的结果形如Map。其中,key是进行分组的字段类型,比如按Ussr类中的type(用户类型:1、2、3、4)进行分组,type的类型为Integer,分组之后的Map的key类型就是Integer。并且最多会分成四组,所以最后的结果即Map
假设我们想用户类型为1的集合,首先先进行分组,如:

Map> userMap = allUserList.parallelStream().collect(Collectors.groupingBy(User::getType));

接下来直接从Map中get(1)即可,如:

List userList  =  userMap.get(1);

Stream之partitioningBy

partitioningBy可以理解为groupingBy的变种或者升级。partition字面意思是‘分区’,也不太好理解。其实partitioningBy是根据‘分区’条件,将集合分成了两组:一组符合‘分区’条件,一组不符合‘分区’条件。分区之后的结果与groupingBy一样,都是形如Map。只是partitioningBy的key只有true/false两种情况,true的部分即符合分区条件集合,false部分为不符合分区条件的集合。
仍然以上述Ussr类为例,假如我们依然想获取到type==1的集合,怎么处理呢?
第一步先进行分区,如:

Map> userMap = allUserList.stream().collect(Collectors.partitioningBy(user -> user.getType() == 1));

然后userMap就被分成了两个区,一个是type为1的集合,一个不是1的集合。接下来get(true)来获取到type为1的集合。如:

List userList  =  userMap.get(true);

groupingBy与partitioningBy之间的坑

1.必须要提的一点是:在进行get时,groupingBy分组若key不存在则返回null,partitioningBy则会返回空数组,groupingBy分组注意判空。
2.stream处理集合的效率并不一定比迭代器高,如果不要求顺序可以使用parallelStream进行并行流的处理。

你可能感兴趣的:(学习笔记,Java规范与细节,Java,Stream)