当前位置: 首页 > news >正文

Java Stream API 编程实战

1. 前言

本文通过一些Stream API的编程题目和示例,来加强对Java函数式编程的理解

2. 题目合集

2.1 求两个列表的并集(降序排列)

// 给定两个整数列表
List<Integer> list1 = Arrays.asList(1, 2, 3, 4, 5, 6);
List<Integer> list2 = Arrays.asList(4, 5, 6, 7, 8, 9);// 预期输出 — [9, 8, 7, 6, 5, 4, 3, 2, 1]

要求:使用Java Stream API编写代码,找出两个列表的并集——即包含所有不重复元素的列表,并按降序排列。

解决方案

public static void main(String args[]) {// 输出 - [9, 8, 7, 6, 5, 4, 3, 2, 1]List<Integer> list1 = Arrays.asList(1, 2, 3, 4, 5, 6);List<Integer> list2 = Arrays.asList(4, 5, 6, 7, 8, 9);// 方案1:使用Stream.of和flatMapList<Integer> unionDescList = Stream.of(list1, list2).flatMap(Collection::stream)  // 将两个列表扁平化为一个流.distinct()                  // 去重.sorted(Comparator.reverseOrder()) // 降序排序.toList();                   // 收集为列表System.out.println("并集(降序): 方案1 - " + unionDescList);// 方案2:使用Stream.concatList<Integer> unionDescList1 = Stream.concat(list1.stream(), list2.stream()).distinct().sorted(Comparator.reverseOrder()).toList();System.out.println("并集(降序): 方案2 - " + unionDescList1);
}

技术要点
• flatMap用于将多个流合并为一个流
• distinct确保元素唯一性
• sorted(Comparator.reverseOrder())实现降序排列
• Java 16+的toList()方法比collect(Collectors.toList())更简洁

2.2 找出满足目标和的元素对

// 给定两个整数列表
List<Integer> list1 = Arrays.asList(1, 2, 3, 6, 17, 1, 10, 8);
List<Integer> list2 = Arrays.asList(1, 17, 12, 12, 2, 4, 6);// 预期输出 — (a, b)形式的元素对

要求:使用Java Stream API编写程序,找出所有满足以下条件的元素对(a, b):
a来自list1,b来自list2,a和b的和为18。

解决方案

public static void main(String args[]) {List<Integer> list1 = Arrays.asList(1, 2, 3, 6, 17, 1, 10, 8);List<Integer> list2 = Arrays.asList(1, 17, 12, 12, 2, 4, 6);// 方案1:使用flatMapSystem.out.println("----方案1 ----");List<String> result = list1.stream().flatMap(a -> list2.stream().filter(b -> a + b == 18).map(b -> a + "," + b)).toList();result.forEach(System.out::println);// 方案2:使用Stream.of和filterSystem.out.println("----方案2 ----");list1.stream().map(a -> list2.stream().filter(b -> a + b == 18).map(b -> a + "," + b)).flatMap(s -> s).forEach(System.out::println);
}

技术要点:
• flatMap用于处理嵌套流结构
• filter条件判断实现业务逻辑

2.3 找出两个列表的共同元素(交集)

// 给定两个整数列表
List<Integer> list1 = Arrays.asList(10, 20, 30, 40, 50);
List<Integer> list2 = Arrays.asList(30, 40, 50, 60, 70);// 预期输出: [30, 40, 50]

要求:使用Java Stream API,找出两个列表中共同的元素(交集),并将它们作为列表返回。

解决方案

public static void main(String args[]) {List<Integer> list1 = Arrays.asList(10, 20, 30, 40, 50);List<Integer> list2 = Arrays.asList(30, 40, 50, 60, 70);// 方案1:使用filter和flatMapSystem.out.println("----方案1 ----");list1.stream().map(a -> list2.stream().filter(b -> Objects.equals(a, b))).flatMap(s -> s).forEach(System.out::println);// 方案2:使用Filter和containsSystem.out.println("----方案2 ----");list1.stream().filter(list2::contains).toList().forEach(System.out::println);
}

技术要点:
• 方案2更简洁高效,推荐在实际开发中使用
• list2::contains是方法引用,相当于b -> list2.contains(b)
• 注意使用Objects.equals进行null安全的比较

2.4 找出列表中所有重复出现的元素

// 给定一个整数列表
List<Integer> list = Arrays.asList(1, 2, 3, 2, 4, 5, 3, 6);// 预期输出: [2, 3]

要求:使用Stream API,找出并返回列表中所有重复出现的元素。

解决方案

public static void main(String args[]) {List<Integer> list = Arrays.asList(1, 2, 3, 2, 4, 5, 3, 6);list.stream()// groupingBy(Function.identity(), counting()) → 统计每个元素的出现次数.collect(Collectors.groupingBy(Function.identity(), Collectors.counting())) .entrySet().stream().filter(a -> a.getValue() > 1) // 只保留出现次数大于1的元素.map(Map.Entry::getKey) // 提取元素本身.toList() // collect(Collectors.toList()) → 收集重复元素到列表.forEach(System.out::println);
}

技术要点:
• groupingBy+counting是统计元素频率的经典组合
• 使用entrySet().stream()将Map转换为流进行处理

2.5 使用Java Stream查找字符串中第一个不重复的字符

// 示例如下
String input = "swiss";/*
• 's'重复出现
• 'w'是唯一的
• 因此,答案应该是:'w'
*/ 

解决方案

public static void main(String args[]) {String input = "swiss";Optional<Character> firstNonRepeating = input.chars()  // 将String转换为IntStream.mapToObj(c -> (char) c)  // 将int值转换为Character对象.collect(Collectors.groupingBy( // 使用LinkedHashMap保持插入顺序,这对找到第一个唯一字符至关重要Function.identity(), LinkedHashMap::new, Collectors.counting() // Collectors.counting() → 统计每个字符的出现次数)).entrySet().stream().filter(entry -> entry.getValue() == 1) // 只保留不重复的字符.map(Map.Entry::getKey).findFirst(); // .map(...).findFirst() → 按插入顺序找到第一个符合条件的字符firstNonRepeating.ifPresent(System.out::println);  // 输出: w
}

技术要点:
• 使用LinkedHashMap保持字符顺序是关键
• findFirst返回Optional,安全处理可能为空的情况

3. 总结

掌握Stream API能极大地提升编写代码的简洁性和表达力,为了更好地掌握其使用,一定要在理解每个Stream方法的工作原理的基础上动手实践。

http://www.lryc.cn/news/609319.html

相关文章:

  • 2025年渗透测试面试题总结-2025年HW(护网面试) 77-1(题目+回答)
  • 《测试驱动的React开发:从单元验证到集成协同的深度实践》
  • 【2025ICCV-目标检测方向】WaveMamba:用于 RGB-红外目标检测的小波驱动曼巴融合
  • 百度招黑产溯源安全工程师
  • SQL注入SQLi-LABS 靶场less31-38详细通关攻略
  • Maxscript在选择的可编辑多边形每个面上绘制一个内部圆形
  • 【高等数学】第七章 微分方程——第十节 常系数线性微分方程组解法举例
  • [硬件电路-140]:模拟电路 - 信号处理电路 - 锁定放大器概述、工作原理、常见芯片、管脚定义
  • 类与对象(中),咕咕咕
  • Zama的使命
  • 零确认双花攻击
  • 8月3日星期日今日早报简报微语报早读
  • 《从原理到实践:MySQL索引优化与SQL性能调优全解析》
  • 【Redis学习路|第一篇】初步认识Redis
  • C的运算符与表达式
  • BP神经网络:当线性模型已到尽头,如何用“人造大脑”挖掘非线性预测规律?
  • 26李林880高数第二章 一元函数微分学及其应用
  • Kafka 是什么?
  • SpringBoot项目数据脱敏(自定义注解)
  • C语言基础03——数组——习题
  • GPIO交换矩阵和IO_MUX
  • 自动驾驶控制算法——LQR控制算法
  • 直流无刷电机(一)
  • C++ <type_traits> 应用详解
  • 10.Redis 数据类型
  • Maximum Subarray Sum II
  • 【超分辨率专题】PiSA-SR:单步Diff超分新突破,即快又好,还能在线调参
  • 【前端:Html】--1.2.基础语法
  • LCL滤波器及其电容电流前馈有源阻尼设计软件【LCLAD_designer】
  • MCU中的复位生成器(Reset Generator)是什么?