Java8的Stream流我看看还有谁不会

最近实习生们写的steam流 一言难尽,简直,看到代码你都来气

我慷慨一把,简单总结一下

当然,Java 8 引入的Stream API为集合处理提供了强大的功能,它支持一系列丰富的中间操作和终端操作。

一、中间操作(Intermediate Operations)

中间操作不会直接执行任何处理,而是创建一个新的流,直到遇到一个终端操作才开始处理。

1. Filter(过滤) 

用于从流中去除不符合条件的元素。

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
   numbers.stream()
          .filter(n -> n % 2 == 0)
          .forEach(System.out::println);

2. Map(转换)

应用于每个元素上的函数,生成一个新的流。

List<String> words = Arrays.asList("hello", "world");
   words.stream()
        .map(String::toUpperCase)
        .forEach(System.out::println);

3. FlatMap(扁平化映射)

将流中的每个值替换成另一个流,然后将所有的流连接成一个流。

List<List<String>> listOfLists = Arrays.asList(
       Arrays.asList("a", "b"),
       Arrays.asList("c", "d")
   );
   listOfLists.stream()
              .flatMap(List::stream)
              .forEach(System.out::println);

4. Sorted(排序)

对流中的元素进行排序。

List<Integer> numbers = Arrays.asList(4, 2, 6, 1, 3, 5);
   numbers.stream()
          .sorted()
          .forEach(System.out::println);

5. Distinct(去重)

去除流中重复的元素。

List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
   numbers.stream()
          .distinct()
          .forEach(System.out::println);

6. Peek(查看)

在每个元素上应用函数并打印或做其他操作,主要用于调试。

List<Integer> numbers = Arrays.asList(1, 2, 3);
   numbers.stream()
          .peek(System.out::println)
          .forEachOrdered(n -> {});

二、终端操作(Terminal Operations)

终端操作会触发实际的计算,并产生一个结果或副作用。

1. forEach(遍历)

对流中的每个元素执行操作。

List<String> greetings = Arrays.asList("Hello", "World");
   greetings.stream()
             .forEach(System.out::println);

2. forEachOrdered(有序遍历)

类似forEach,但保证按照流的 encounter order 处理元素。

List<String> greetings = Arrays.asList("Hello", "World");
   greetings.stream()
             .forEachOrdered(System.out::println);

3. reduce(规约)

将流中的元素组合起来,生成一个单一的结果。

List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
   int sum = numbers.stream()
                    .reduce(0, Integer::sum);
   System.out.println(sum);

4. collect(收集)

将流的元素收集到一个集合、Map或其他容器中。

List<String> words = Arrays.asList("hello", "world");
   List<String> upperCaseWords = words.stream()
                                      .map(String::toUpperCase)
                                      .collect(Collectors.toList());

5. anyMatch、allMatch、noneMatch(匹配)

判断流中是否有元素满足、全部满足或都不满足指定条件。

boolean anyStartsWithH = words.stream()
                                 .anyMatch(s -> s.startsWith("H"));
   System.out.println(anyStartsWithH);

6. findFirst、findAny(查找)

查找第一个或任意一个匹配指定条件的元素。

Optional<String> firstWord = words.stream()
                                     .filter(s -> s.length() > 5)
                                     .findFirst();

7. count(计数)

计算流中元素的数量。

long evenCount = numbers.stream()
                           .filter(n -> n % 2 == 0)
                           .count();

8. min、max(最小值、最大值)

找到流中的最小或最大元素。

Optional<Integer> maxNumber = numbers.stream()
                                        .max(Integer::compareTo);

三、更复杂的Stream处理示例

1、分组(Grouping)

假设我们有一个Person类,包含属性age和gender,我们可以按年龄和性别分组统计人数

class Person {
    String name;
    int age;
    String gender;
    // 构造方法、getters、setters省略
}

List<Person> people = Arrays.asList(
    new Person("Alice", 30, "F"),
    new Person("Bob", 25, "M"),
    new Person("Charlie", 30, "M"),
    // 更多数据...
);

Map<Integer, Map<String, Long>> groupByAgeAndGender = people.stream()
    .collect(Collectors.groupingBy(
        Person::getAge,
        Collectors.groupingBy(Person::getGender, Collectors.counting())
    ));

System.out.println(groupByAgeAndGender);

2、分区(Partitioning)

根据条件将流分为两部分。

Map<Boolean, List<Person>> partitionedByAge = people.stream()
    .collect(Collectors.partitioningBy(p -> p.getAge() > 30));

System.out.println(partitionedByAge);

3、收集到自定义结构(Collect to custom structure)

假设我们要构造一个自定义报告结构,包含每个年龄的平均工资。

class AgeSalaryReport {
    int age;
    double averageSalary;
    // getters、setters省略
}

List<AgeSalaryReport> salaryReports = people.stream()
    .collect(Collectors.groupingBy(Person::getAge))
    .entrySet().stream()
    .map(entry -> new AgeSalaryReport(
        entry.getKey(),
        entry.getValue().stream()
            .mapToInt(Person::getSalary)
            .average()
            .orElse(0.0)
    ))
    .collect(Collectors.toList());

System.out.println(salaryReports);

4、连接多个Stream操作

结合排序、过滤、映射等操作处理复杂逻辑。

class Task {
    String name;
    int priority;
    LocalDateTime createTime;
    // 构造方法、getters、setters省略
}

List<Task> tasks = Arrays.asList(
    // 初始化任务列表...
);

List<Task> highPriorityRecentTasks = tasks.stream()
    .filter(task -> task.getPriority() >= 5) // 过滤出高优先级任务
    .sorted(Comparator.comparing(Task::getPriority).reversed() // 按优先级降序
        .thenComparing(Task::getCreateTime).reversed()) // 再按创建时间降序
    .limit(10) // 取前10个
    .collect(Collectors.toList());

System.out.println(highPriorityRecentTasks);
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值