Stream流技巧总结
Stream 流技巧总结
前言
Java 中的 Stream 流提供了一种强大而灵活的处理集合数据的方式。通过 Stream,我们可以使用更为简洁和函数式的风格对集合进行操作,提高代码的可读性和可维护性。在本文中,笔者将总结一些常用的 Stream 流技巧,涵盖了抽取、转换和过滤集合数据的常见场景。当然,后续笔者接触到了其他的场景,也会同步更新文章内容,推荐点赞加收藏哦。
抽取列表元素属性整合成列表集合
利用 stream 流的 map
方法:
// 获取List的【id集合】 List<Long> ids = list.stream().map(LearningLesson::getId).collect(Collectors.tolist()); // 获取Set的【id集合】 Set<Long> ids2 = list,stream().map(LearningLesson;:getId).collect(Collectors.toSet());
LearningLesson 是一个实体类。
list 转 Map
1、传统写法 - new 一个 Map
Map<Long, LearningLesson> map = new HashMap<>(); for (LearningLesson lesson : list) { map.put(lessson.getId(), lesson); }
2、使用 stream 流
当要使用两个 for 循环的时候,这种方法可能可以用来提高性能。
// toMap 方法 Map<Long, LearningLesson> lessonMap = list.stream() .collect(Collectors.toMap(LearningLesson::getId, c -> c)); // c -> c 等价于 Function.identity() // Function.identity() 是 Java 8 引入的一个方法,它返回一个函数,该函数总是返回其输入参数。简单来说,它是一个用于创建恒等函数的静态方法。 Map<Long, LearningLesson> lessonMap = list.stream() .collect(Collectors.toMap(LearningLesson::getId, Function.identity())); // 其他用法 Map<Long, Long> lessonMap = list.stream() .collect(Collectors.toMap(LearningLesson::getId, c -> c.getCourseId));
3、Collectors.groupingBy 方法
Map<Long, List<LearningLesson>> lessonMap = list.stream() .collect(Collectors.groupingBy(LearningLesson::getObjId));
注意:
- 需考虑
LearningLesson::getId
是否会有重复数据的情况 - 在使用
Collectors.groupingBy
进行分组时,如果被分组的属性(这里是LearningLesson::getObjId
)存在重复的情况,那么结果就会是将具有相同属性值的元素放入同一个列表中。 - 是会放入同一个列表中,而不是覆盖。
filter 过滤
基本用法
过滤偶数
public class FilterExample { public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // 使用 filter 过滤出偶数 List<Integer> evenNumbers = numbers.stream() .filter(n -> n % 2 == 0) .collect(Collectors.toList()); // 打印结果 System.out.println("原始列表:" + numbers); System.out.println("过滤后的偶数列表:" + evenNumbers); } }
过滤对象
Long maintainerId = documentInfo.getObjId(); MaintainerEntity maintainer = list.stream() .filter(m -> m.getId().equals(maintainerId)) .findFirst() .orElse(null);
解释
list.stream()
: 将集合list
转换为一个流(Stream)对象,这样我们就可以使用流的各种操作。.filter(m -> m.getId().equals(maintainerId))
: 使用filter
操作,保留满足给定条件的元素。在这里,保留那些m
对象,其id
属性与给定的maintainerId
相等。.findFirst()
: 获取满足条件的第一个元素。这里,我们得到的是一个Optional
对象,因为可能找不到符合条件的元素。.orElse(null)
: 如果有符合条件的元素,返回该元素;否则,返回null
。这里的null
是作为默认值传递的。
总结
- 这段代码的目的是从
list
集合中找到一个具有指定maintainerId
的MaintainerEntity
对象。如果找到了,则返回该对象,否则返回null
。 - 这种写法的好处在于它简洁而流畅地表达了查找的过程,同时通过使用
Optional
类型避免了空指针异常,因为findFirst()
可能找不到匹配的元素。
结合 Predicate 使用
filter
方法接受一个 Predicate
参数,该参数是一个函数接口,用于定义过滤条件。我们可以将一个自定义的 Predicate
传递给 filter
方法,以实现更灵活的过滤条件。
例如,我们定义一个 Predicate
用于判断一个数字是否为质数:
public class FilterWithPredicate { public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // 定义 Predicate 判断是否为质数 Predicate<Integer> isPrime = n -> { if (n <= 1) { return false; } for (int i = 2; i <= Math.sqrt(n); i++) { if (n % i == 0) { return false; } } return true; }; // 使用 filter 过滤出质数 List<Integer> primeNumbers = numbers.stream() .filter(isPrime) .collect(Collectors.toList()); // 打印结果 System.out.println("原始列表:" + numbers); System.out.println("过滤后的质数列表:" + primeNumbers); } }
去除查询结果中的重复元素
思路分析
- 首先使用
Stream.map()
方法将list
中的每个FormEntity
对象的type
字段提取出来, - 然后使用
Collectors.toSet()
方法将这些type
值收集到一个不包含重复元素的Set
集合中。 - 最后,再将这个
Set
集合转换回List
。
这样,返回的 uniqueTypes
列表就不会有重复的元素了。
代码
List<Integer> uniqueTypes = list.stream() .map(FormEntity::getType) .collect(Collectors.toSet()) .stream() .collect(Collectors.toList());
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix