当前位置: 首页 > 工具软件 > streama > 使用案例 >

Java8种Stream流相关操作——集合的筛选、归约、分组、聚合

艾俊晖
2023-12-01

一、概述

在Java8中,使用Stream配合同版本出现的Lambda,给我们操作集合(Collection)提供了极大的便利。
Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作,比如:筛选、排序、聚合等。

二、Stream流的创建

Stream流可以通过集合、数组来创建。

  • 通过集合来进行创建
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
list.stream().forEach(i->{
    System.out.println(i);
});
  • 通过数组来创建
String[] nums={"a", "b", "c"};
Stream<String> stream = Arrays.stream(nums);
Arrays.stream(nums).forEach(i->{
    System.out.println(i);
});

三、使用

3.1 遍历、匹配

  • forEach
List<Integer> list = Arrays.asList(10, 5, 8, 20, 32, 6);
// 遍历输入每一个元素
list.stream().forEach(item -> {
    System.out.println(item);
});
  • match
List<Integer> list = Arrays.asList(10, 5, 8, 20, 32, 6);
// list集合中是否有大于30的数
boolean b = list.stream().anyMatch(i -> i > 30);   // true
// list集合中是否有大于50的数
boolean b2 = list.stream().anyMatch(i -> i > 50);   // false
  • find
List<Integer> list = Arrays.asList(10, 5, 8, 20, 32, 6);
// 获取第一个值
Integer integer = list.stream().findFirst().get();   // 10

3.2、筛选

  • filter
//筛选出大于7的数
List<Integer> list = Arrays.asList(10, 5, 8, 20, 7, 6);
// 打印list集合中所有的奇数
list.stream().filter(i -> i >7).forEach(System.out::println);
  • skip
    skip()方法用于跳过前面n个元素,然后再返回新的流
List<Integer> nums=Arrays.asList(1,2,3,4,5);
List<Integer> collect = nums.stream().skip(2).collect(Collectors.toList());
System.out.println(collect);
  • limit
    limit()是用于限制流中元素的个数,即取前n个元素,返回新的流
List<Integer> nums=Arrays.asList(1,2,3,4,5);
List<Integer> collect = nums.stream().limit(2).collect(Collectors.toList());
System.out.println(collect);
  • limit和skip组合可以实现string中的sublist()方法
List<Integer> nums=Arrays.asList(1,2,3,4,5);
List<Integer> collect = nums.stream().skip(2).limit(2).collect(Collectors.toList());
System.out.println(collect);

3.3、聚合

  • max、min
List<String> list = Arrays.asList("jack", "tom", "alice");
// 取出list中最长的字符串
String max = list.stream().max(Comparator.comparing(String::length)).get();   // alice
String min = list.stream().min(Comparator.comparing(String::length)).get();   // tom
  • count
List<Integer> list = Arrays.asList(10, 5, 8, 20, 7, 6);
// 获取list集合中偶数的个数
long count = list.stream().filter(i -> i % 2 == 0).count();   // 4
  • sum
List<Integer> list = Arrays.asList(10, 5, 8, 20, 7, 6);
int sum = list.stream().mapToInt(Integer::intValue).sum();
System.out.println(sum);

3.4、映射

  • map
    将list集合中名字全部专大写,映射为list2,list集合中的不变
List<String> list = Arrays.asList("jack", "tom", "alice");
// 名字全转大写
List<String> list2 = list.stream().map(String::toUpperCase).collect(Collectors.toList());   // [JACK, TOM, ALICE]
System.out.println(list2);

list集合种每个数都加100

List<Integer> list = Arrays.asList(10, 5, 8, 20, 7, 6);
// 每个都加100
List<Integer> list2 = list.stream().map(i -> i + 100).collect(Collectors.toList());   // [110, 105, 108, 120, 107, 106]

将对象列表转为字符串列表

List<Student> list = Arrays.asList(
        new Student(1, "jack"),
        new Student(2, "alice"),
        new Student(3, "tom")
);
// 将对象列表转为字符串列表
List<String> names = list.stream().map(student -> student.getName()).collect(Collectors.toList());   // [jack, alice, tom]
  • mapToInt (类似与拆箱,将Integer转换为int)
Integer[] nums={1,5,3};
int[] ints = Arrays.stream(nums).mapToInt(Integer::intValue).toArray();
  • boxed (boxed的作用就是将int类型的stream转成了Integer类型的Stream)
int[] nums={1,5,3};
Integer[] num= Arrays.stream(nums).boxed().toArray(Integer[]::new);

3.5、归约

reduce

List<Integer> list = Arrays.asList(10, 5, 8, 20, 7, 6);
// 求集合元素之和
Integer num = list.stream().reduce(Integer::sum).get();   // 56

3.6、收集

  • toList
List<Integer> list = Arrays.asList(10, 5, 8, 20, 7, 6);
// 找出集合中的偶数,并返回新的集合
List<Integer> newList = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());   // [10, 8, 20, 6]
  • toSet
List<Integer> list = Arrays.asList(10, 5, 8, 20, 7, 6);
// 找出集合中的偶数,并返回新的集合
Set<Integer> set = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toSet());   // [20, 6, 8, 10]

3.8 去重

  • distinct
int[] nums={1,5,3,3};
List<Integer> collect = Arrays.stream(nums).distinct().boxed().collect(Collectors.toList());
System.out.println(collect);

3.9 分组排序

  • 用leetcode一个题目来介绍
    题目
    给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
    字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
  • java代码
class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        return new ArrayList<>(Arrays.stream(strs)
            .collect(Collectors.groupingBy(str -> {
                // 返回 str 排序后的结果。
                // 按排序后的结果来grouping by,算子类似于 sql 里的 group by。
                char[] array = str.toCharArray();
                Arrays.sort(array);
                return new String(array);
            })).values());
    }
}

注意 groupingBy 算子计算完以后,返回的是一个 Map<String, List>,map 的键是每种排序后的字符串,值是聚合的原始字符串,我们只关心值,所以我们最后 new ArrayList<>(map.values())。

 类似资料: