news 2026/6/9 13:16:24

Java Stream(java.util.stream.*)从 0 到“进阶实战”一次性梳理出来

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java Stream(java.util.stream.*)从 0 到“进阶实战”一次性梳理出来
  1. 创建流(7 种常用入口)

    Stream<String> s1 = Stream.of("a", "b", "c"); Stream<String> s2 = Arrays.stream(arr); Stream<String> s3 = list.stream(); // 集合 Stream<String> s4 = Files.lines(Paths.get("a.txt")); // IO Stream<Integer> s5 = Stream.iterate(0, n -> n + 2); // 无限流 Stream<Integer> s6 = Stream.generate(() -> 1); // 无限流 IntStream s7 = IntStream.range(1, 100); // 基本类型
  2. 中间操作(lazy,链式)

    stream .filter(x -> x % 2 == 0) // 过滤 .map(String::valueOf) // 1:1 转换 .flatMap(x -> Arrays.stream(x.split(","))) // 1:N 打平 .distinct() // 去重 .sorted(Comparator.comparing(User::getAge).reversed()) .peek(System.out::println) // 调试打印,不会触发消费 .limit(5) // 截断 .skip(3) // 跳过 .takeWhile(x -> x < 50) // Java9+ 遇到第一个 false 停止 .dropWhile(x -> x < 50); // Java9+ 丢掉前缀
  3. 终端操作(触发执行)

    // 3.1 遍历/消费 forEach(System.out::println); // 3.2 聚合 long cnt = stream.count(); Optional<Integer> max = stream.max(Integer::compare); Integer sum = stream.mapToInt(Integer::intValue).sum(); OptionalDouble avg = stream.mapToInt(Integer::intValue).average(); // 3.3 规约 Integer total = stream.reduce(0, Integer::sum); String joined = stream.reduce("", (a, b) -> a + "," + b); // 3.4 收集(最灵活) List<String> list = stream.collect(Collectors.toList()); Set<String> set = stream.collect(Collectors.toSet()); Map<String, User> map = stream.collect(Collectors.toMap(User::getId, u -> u)); String csv = stream.collect(Collectors.joining(";")); Map<Integer, List<User>> group = stream.collect(Collectors.groupingBy(User::getAge)); Map<Boolean, List<User>> part = stream.collect(Collectors.partitioningBy(u -> u.getAge() >= 18)); // 3.5 匹配/查找 boolean ok1 = stream.allMatch(x -> x > 0); boolean ok2 = stream.anyMatch(x -> x > 0); boolean ok3 = stream.noneMatch(x -> x > 0); Optional<Integer> first = stream.findFirst(); Optional<Integer> any = stream.findAny(); // 3.6 转数组/基本类型流 int[] arr = stream.mapToInt(Integer::intValue).toArray();
  4. 基本类型特化流(IntStream / LongStream / DoubleStream)

    IntStream.rangeClosed(1, 100) .filter(n -> n % 7 == 0) .average() .ifPresent(System.out::println);
  5. 并行流(parallel)与并发注意

    long c = LongStream.rangeClosed(1, 1_0000_0000L) .parallel() // 拆分成多段 ForkJoin .filter(n -> n % 103 == 0) .count();

    注意:

  • 数据量小别用,线程切换反而慢

  • 避免有状态 lambda、外部共享变量

  • Collectors.toConcurrentMap可进一步减少锁

6.自定义收集器(Collector 接口)

Collector<Integer, StringJoiner, String> myJoin = Collector.of( () -> new StringJoiner("、"), (j, s) -> j.add(s.toString()), (j1, j2) -> j1.merge(j2), StringJoiner::toString); String r = Stream.of(1, 2, 3).collect(myJoin); // 1、2、3

7.与 Optional 联动

stream.map(User::getAddress) .filter(Objects::nonNull) .findFirst() .ifPresent(addr -> System.out.println("找到地址:" + addr));

8.实战 10 例(一行流)

// 1. 去重并按字典序取前 3 List<String> top3 = list.stream().distinct().sorted().limit(3).toList(); // 2. 把两个 List 合并后去重 List<String> union = Stream.concat(list1.stream(), list2.stream()) .distinct() .toList(); // 3. 统计每个单词出现次数 Map<String, Long> freq = words.stream() .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); // 4. 找到工资最高的员工 Optional<Employee> richest = emps.stream() .max(Comparator.comparingDouble(Employee::getSalary)); // 5. 按部门分组后,取每组工资最高的 Map<Department, Optional<Employee>> topInDept = emps.stream() .collect(Collectors.groupingBy(Employee::getDept, Collectors.maxBy(Comparator.comparingDouble(Employee::getSalary)))); // 6. 把 List<User> 转 Map<id, name> Map<Long, String> id2Name = users.stream() .collect(Collectors.toMap(User::getId, User::getName)); // 7. 将字符串列表转整型,跳过非数字 List<Integer> nums = strList.stream() .filter(s -> s.matches("\\d+")) .map(Integer::valueOf) .toList(); // 8. 把多行配置按“键=值”解析成 Map Map<String, String> cfg = lines.stream() .filter(l -> l.contains("=")) .map(l -> l.split("=", 2)) .collect(Collectors.toMap(a -> a[0], a -> a[1])); // 9. 分页:跳过前 (page-1)*size 条,取 size 条 List<Row> page = rows.stream() .skip((pageNo - 1) * pageSize) .limit(pageSize) .toList(); // 10. 递归列出目录下所有 .java 文件 try (Stream<Path> walk = Files.walk(Paths.get("src"))) { List<File> javaFiles = walk.filter(p -> p.toString().endsWith(".java")) .map(Path::toFile) .toList(); }

9.常见坑

  • stream只能消费一次,再调会抛IllegalStateException

  • peek里别改外面状态,调试完就删。

  • parallel不一定快,先度量。

  • toMap遇到重复 key 默认抛异常,用(v1,v2)->v2指定冲突策略。

  • sorted会缓存整个流,大数据慎用。

开发中经常遇到stream的问题,就整理了一份,希望对大家有帮助!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/7 23:40:06

傅里叶变换、拉普拉斯变换、Z 变换的定义及关系

文章目录一、 三种变换的定义1. 连续时间信号的傅里叶变换&#xff08;FT&#xff09;2. 连续时间信号的拉普拉斯变换&#xff08;LT&#xff09;3. 离散时间信号的Z变换&#xff08;ZT&#xff09;二、 三种变换的关系1. 傅里叶变换与拉普拉斯变换的关系2. 傅里叶变换与 Z 变换…

作者头像 李华
网站建设 2026/6/8 6:15:23

C#特性(Attributes)详解

第一部分&#xff1a;特性是什么&#xff1f;&#xff08;类比贴标签&#xff09;1.1 最简单的理解想象一下你在图书馆看书&#xff0c;你可能会&#xff1a;在重要的页面贴书签&#xff08;标记重要内容&#xff09;在书封面上贴标签&#xff08;如"新书"、"推…

作者头像 李华
网站建设 2026/6/9 1:08:08

8 个文献综述工具推荐,本科生论文写作更轻松!

8 个文献综述工具推荐&#xff0c;本科生论文写作更轻松&#xff01; 论文写作的“三座大山”&#xff1a;时间、重复率与效率 对于本科生来说&#xff0c;毕业论文从来不是一件轻松的事情。尤其是文献综述部分&#xff0c;常常让人感到无从下手。面对海量的学术资料&#xff0…

作者头像 李华
网站建设 2026/6/7 16:55:41

9 个开题演讲稿 AI 工具,本科生论文写作推荐

9 个开题演讲稿 AI 工具&#xff0c;本科生论文写作推荐 论文路上的“三座大山”&#xff1a;时间、重复率与灵感枯竭 对于每一位本科生来说&#xff0c;撰写开题报告和演讲稿都是一段既紧张又充满挑战的旅程。从选题到文献综述&#xff0c;从框架搭建到内容填充&#xff0c;…

作者头像 李华
网站建设 2026/6/7 19:37:01

LangChain模板调用Qwen-Image-Edit-2509实现标准化图像修改

LangChain模板调用Qwen-Image-Edit-2509实现标准化图像修改 在电商运营的日常中&#xff0c;一个常见的场景是&#xff1a;距离大促上线只剩两小时&#xff0c;市场团队突然决定将“限时折扣”改为“爆款直降”&#xff0c;几十张商品主图需要统一更新文案和背景风格。如果依赖…

作者头像 李华
网站建设 2026/6/7 1:15:20

智慧楼宇厕所解决方案实现远程管控

随着移动互联网与物联网技术的全面普及&#xff0c;我们计划深度整合物联网、传感检测、云计算及大数据分析等前沿技术&#xff0c;搭建一体化智慧厕所管理平台。通过创新管理模式&#xff0c;实现公共厕所的智能化监测、精细化运营与高效管理&#xff0c;打通线上线下服务壁垒…

作者头像 李华