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

商城网站主机在线制作论坛网站

商城网站主机,在线制作论坛网站,织梦网站后台,温州网站建设科技有限公司我们来深入剖析 Stream API 中最核心、最常用的“三巨头”:filter、map 和 collect。理解了它们,你就掌握了 Stream 大半的精髓。1. filter() - 过滤器 是什么? filter 是一个中间操作。它就像一个大筛子或一个过滤器,用于从流中筛…

我们来深入剖析 Stream API 中最核心、最常用的“三巨头”:filtermapcollect。理解了它们,你就掌握了 Stream 大半的精髓。


1. filter() - 过滤器

是什么?

filter 是一个中间操作。它就像一个大筛子或一个过滤器,用于从流中筛选出满足特定条件的元素

怎么工作?
  • 参数:它接受一个 Predicate<? super T> 函数式接口作为参数。
    • Predicate 是一个“断言函数”,它接收一个参数,返回一个 boolean 值(truefalse)。
  • 逻辑:流中的每一个元素都会被传递给 Predicatetest 方法。
    • 如果 test 方法返回 true,该元素会被保留并传递到下一个操作。
    • 如果返回 false,该元素会被过滤掉。
  • 返回值:返回一个新的 Stream<T>,包含所有被保留的元素。
代码示例
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Anna", "Edward");// 过滤出所有以字母 "A" 开头的名字
List<String> namesStartingWithA = names.stream().filter(name -> name.startsWith("A")) // Predicate: 输入name,返回boolean.collect(Collectors.toList());System.out.println(namesStartingWithA); // 输出: [Alice, Anna]// 过滤出长度大于 3 的名字
List<String> longNames = names.stream().filter(name -> name.length() > 3).collect(Collectors.toList());System.out.println(longNames); // 输出: [Alice, Charlie, David, Anna, Edward]

2. map() - 映射/转换器

是什么?

map 是一个中间操作。它就像一个加工机床,用于将流中的每个元素转换成另一个形式。它是一对一的映射,原元素会被新元素替换。

怎么工作?
  • 参数:它接受一个 Function<? super T, ? extends R> 函数式接口作为参数。
    • Function 是一个“转换函数”,它接收一个参数(类型 T),返回一个结果(类型 R)。
  • 逻辑:流中的每一个元素都会被传递给 Functionapply 方法,并将该方法的返回值(可以是任何类型)组成一个新的流。
  • 返回值:返回一个 Stream<R>,流的元素类型可能已经从 T 改变为了 R
代码示例
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");// 1. 将每个字符串映射为它的长度(将 String 转换为 Integer)
List<Integer> nameLengths = names.stream().map(name -> name.length()) // Function: 输入String,返回Integer.collect(Collectors.toList());
System.out.println(nameLengths); // 输出: [5, 3, 7]// 2. 将每个字符串转换为大写
List<String> upperCaseNames = names.stream().map(String::toUpperCase) // 使用方法引用,等价于 .map(s -> s.toUpperCase()).collect(Collectors.toList());
System.out.println(upperCaseNames); // 输出: [ALICE, BOB, CHARLIE]// 更复杂的例子:从对象中提取特定字段
class Person {private String name;private int age;// 省略构造方法和getter/setter
}
List<Person> people = Arrays.asList(new Person("Alice", 25),new Person("Bob", 30)
);// 将 Person 流映射为 String 流(只包含名字)
List<String> onlyNames = people.stream().map(person -> person.getName()) // 输入Person,输出String.collect(Collectors.toList());
System.out.println(onlyNames); // 输出: [Alice, Bob]// 将 Person 流映射为 Integer 流(只包含年龄)
List<Integer> onlyAges = people.stream().map(Person::getAge) // 使用方法引用.collect(Collectors.toList());
System.out.println(onlyAges); // 输出: [25, 30]

3. collect() - 收集器/终结者

是什么?

collect 是一个终结操作。它是流水线的终点站,用于将流中的元素聚合、汇总到一个容器中(如 List, Set, Map)或生成一个值。它会触发整个流的实际执行。

怎么工作?
  • 参数:它接受一个 Collector<? super T, A, R> 接口的参数。
    • 幸运的是,我们很少自己实现这个接口,而是使用 Collectors 工具类提供的各种静态工厂方法。
  • 逻辑:它根据传入的 Collector 策略,对流中的元素进行可变缩减(mutable reduction),将元素累积到一个结果容器中。
  • 返回值:返回一个类型为 R 的结果,通常是一个集合或一个值。
常用 Collectors 方法示例
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Anna", "Bob");// 1. 收集到 List (最常用)
List<String> list = names.stream().filter(name -> name.length() > 3).collect(Collectors.toList()); // 返回 ArrayList// 2. 收集到 Set (自动去重)
Set<String> set = names.stream().collect(Collectors.toSet()); // 返回 HashSet, 输出: [Alice, Bob, Charlie, David, Anna] (只有一个Bob)// 3. 收集到指定的集合类型,例如 TreeSet
TreeSet<String> treeSet = names.stream().collect(Collectors.toCollection(TreeSet::new)); // 可以指定集合的具体实现// 4. 连接字符串:将所有元素用分隔符连接起来
String joined = names.stream().collect(Collectors.joining(", ")); // 参数是分隔符
System.out.println(joined); // 输出: Alice, Bob, Charlie, David, Anna, Bob// 5. 分组:按条件分组,返回一个 Map
// 按名字的首字母分组
Map<Character, List<String>> groupByFirstLetter = names.stream().collect(Collectors.groupingBy(name -> name.charAt(0)));
System.out.println(groupByFirstLetter);
// 输出: {A=[Alice, Anna], B=[Bob, Bob], C=[Charlie], D=[David]}// 6. 分区:是分组的一种特例,按true/false分区(满足条件和不满足条件的)
// 将名字分为长度大于3和不超过3的两部分
Map<Boolean, List<String>> partitioned = names.stream().collect(Collectors.partitioningBy(name -> name.length() > 3));
System.out.println(partitioned);
// 输出: {false=[Bob, Bob], true=[Alice, Charlie, David, Anna]}

组合使用:威力无穷

真正的威力在于将它们组合成一条声明式的流水线。

任务:有一个名字列表,要求:

  1. 过滤掉长度小于等于3的。
  2. 将所有名字转换为大写。
  3. 按字母顺序排序。
  4. 收集到一个新的 ArrayList 中。
List<String> names = Arrays.asList("Chris", "Alice", "Bob", "David", "Eve");List<String> processedNames = names.stream()         // 获取流.filter(name -> name.length() > 3)          // 1. 过滤.map(String::toUpperCase)                   // 2. 转换.sorted()                                   // 3. 排序.collect(Collectors.toList());              // 4. 收集System.out.println(processedNames); // 输出: [ALICE, CHRIS, DAVID]

总结对比

方法类型目的参数返回值
filter中间操作筛选元素Predicate<T> (返回boolean)Stream<T>
map中间操作转换元素Function<T, R> (T->R)Stream<R>
collect终结操作收集元素到容器Collector<? super T, A, R>R (通常是一个集合)

记住这个流程:获取流 -> 过滤(filter) -> 转换(map) -> 收集(collect)。这个模式可以解决你日常开发中绝大部分的数据处理需求。多练习,你就会越来越习惯这种声明式的优雅编程风格。

http://www.dtcms.com/a/409836.html

相关文章:

  • 网站建设扌金手指六六wordpress开源可视化编辑
  • SpringData
  • linux docker 离线 安装
  • MyBatis常见面试题
  • Docker(一)—— Docker入门到精通:从基础概念到容器管理
  • python(44) : docker compose基于基础镜像部署python服务
  • VMware+RockyLinux+ikuai+docker+cri-docker+k8s+calico BGP网络 自用 实践笔记(四)
  • 深入理解 Docker:从入门到实践
  • 实战排查:Java 解析 Excel 大型 导致内存溢出问题的完整解决过程
  • 【实录】使用 Verdaccio 从零搭建私有 npm 仓库(含完整步骤及避坑指南)
  • 物联网人体红外检测系统详解
  • 关于Unix Domain Socket的使用入门
  • 机器视觉系统中工业相机的常见类型及其特点、应用
  • RTT操作系统(4)
  • 基于卷积神经网络的 CIFAR-10 图像分类实验报告
  • 微服务项目->在线oj系统(Java-Spring)----[前端]
  • 做网站撘框架小米手机如何做游戏视频网站
  • 如何建自己网站做淘宝客黄骅港吧
  • 交叉口内CAV调度:轨迹优化与目标速度规划,助力智能交通无缝运行!
  • Navicat 技术指引 | KingbaseES 专用 AI 助手
  • 如何优化Android app耗电量
  • 面试复习题---Flutter 资深专家
  • 在 C# 中将邮件转换为 PDF | MSG 转 PDF | EML 转 PDF
  • 【LangChain4j+Redis】会话记忆功能实现
  • Android Handler的runWithScissors方法
  • 180课时吃透Go语言游戏后端开发3:Go语言中其他常用的数据类型
  • 在 Android 11 上实现 WiFi 热点并发支持(同时开启 STA + AP 模式)
  • 济南高新区网站建设wordpress举报插件
  • html 占位符
  • GPT-5 Codex正式上线 Azure AI Foundry(国际版)