我们一起聊聊 Java Steam 常用 API
现在 Java 17 和 Java 11 基本上可以和 Java8 平分 JDK 装机比例。下面是我常用的一些 Strem API 操作。除了分组、转换、排序,如果大家还有更多常用的 API 可以一起留言交流。
分组
List 默认分组过后是 Map
List streamList = Stream.of( new StreamItem(1, "k1"), new StreamItem(2, "k1"), new StreamItem(3, "k2"), new StreamItem(4, "k2")).collect(Collectors.toList()); System.out.println(streamList); //1.1分组 Map streamMap1 = streamList.stream().collect(Collectors.groupingBy(StreamItem::getKey)); System.out.println(streamMap1); //输出: {k1=[StreamItem{id=1, key='k1', name='i_1|k_k1'}, StreamItem{id=2, key='k1', name='i_2|k_k1'}], k2=[StreamItem{id=3, key='k2', name='i_3|k_k2'}, StreamItem{id=4, key='k2', name='i_4|k_k2'}]}
List 默认分组过后是 Map
//1.2分组只拿第一个 Map streamMap2 = Stream.of( new StreamItem(1, "k1"), new StreamItem(2, "k2")).collect(Collectors.toMap(StreamItem::getKey, Function.identity())); //如果 key 重复报: java.lang.IllegalStateException: Duplicate key System.out.println(streamMap2); //输出: {k1=StreamItem{id=1, key='k1', name='i_1|k_k1'}, k2=StreamItem{id=2, key='k2', name='i_2|k_k2'}}
分组,在组内排序然后获取最大值,或者最小值
Comparator idComparator =Comparator.comparing(StreamItem::getId); Map streamMap3 = streamList.stream().collect(Collectors.groupingBy(StreamItem::getKey, Collectors.reducing(BinaryOperator.maxBy(idComparator)))); System.out.println(streamMap3); //输出 {k1=Optional[StreamItem{id=2, key='k1', name='i_2|k_k1'}], k2=Optional[StreamItem{id=4, key='k2', name='i_4|k_k2'}]}
List 转换为 List
这个也是超级实用的 api
List partitionList = Lists.partition(streamList, 2); List streamList1 = partitionList.stream().flatMap(Collection::stream).collect(Collectors.toList()); System.out.println(streamList1); //输出 [StreamItem{id=1, key='k1', name='i_1|k_k1'}, StreamItem{id=2, key='k1', name='i_2|k_k1'}, StreamItem{id=3, key='k2', name='i_3|k_k2'}, StreamItem{id=4, key='k2', name='i_4|k_k2'}]
排序
排序,默认正序,如果是需要倒序,可以在comparing 方法后面再调用 reversed 方法
//3.1 正序 List streamList2 = Stream.of( new StreamItem(3, "k1"), new StreamItem(1, "k1"), new StreamItem(2, "k2")) //倒序:Comparator.comparing(StreamItem::getId).reversed() .sorted(Comparator.comparing(StreamItem::getId)).collect(Collectors.toList()); System.out.println(streamList2);
去重
去重复后,保留最后写入的值
//4.1 去重复 List streamList3 = Stream.of( new StreamItem(3, "k1"), new StreamItem(1, "k1"), new StreamItem(2, "k2")) //如果只需要保留最大的 id 的值,就可以先排序, 时间复杂度考了个人觉得实用 group 更优 .sorted(Comparator.comparing(StreamItem::getId).reversed()) .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> //利用 set 特征去重 new TreeSet(Comparator.comparing(StreamItem::getKey))), ArrayList::new)); System.out.println(streamList3); //输出: [StreamItem{id=3, key='k1', name='i_3|k_k1'}, StreamItem{id=2, key='k2', name='i_2|k_k2'}]
其他常用 API
- filter(按照条件过滤需要数据)
- max(取出流中的最大值)
- min(取出流中的最小值)
- count(取出流中的数量)
- sum(取出流中数据的和)
- average(取出流中数据的平均值)
- distinct(将流中的数据去重)
- sorted(自然排序,默认为升序,可以设置为升序排序或者降序排序)
- limit,skip (限制和跳过:可以将流数据的部分截取,可用于后台的分页场景)
- map(映射转换)
- collect,toList(不可以对集合去重)
- collect, toSet(可以集合去重)
- toArray(将流数据转为数组)
- mapToInt,distinct(将流数据转成IntStream,并去重)
- reduce 求和
- reduce 求最大值
- reduce 求最小值
- reduce 求乘积
- findFirst(查找第一个元素)
- findAny(任意查找一个元素)
- allMatch(判断是否全部满足条件,全部满足返回 true,否则返回false)
- anyMatch(判断是否有一个满足条件,只要有一个满足就返回 true,否则都不满足返回false)
- noneMatch(判断是否都不满足条件,都不满足返回true,否则返回false)
- flatmap(扁平化流处理)