Java Stream的map操作用于将流中每个元素按指定规则一对一转换为新元素,返回新流且不修改原流;它接收Function接口,支持字符串转大写、数值计算、对象字段提取等纯函数式转换,要求映射结果非null、无副作用。

Java Stream 的 map 操作用于将流中每个元素按指定规则转换为另一个元素,实现一对一的类型转换与映射,返回新流,原流不变。
map 的基本用法与核心逻辑
map 接收一个 Function
- 必须是“一对一”:输入一个元素,输出且仅输出一个元素
- 不能为 null:若映射函数返回 null,后续操作(如 collect)可能抛出 NullPointerException
- 适合纯函数式转换:如字符串转大写、对象取字段、数值计算等
常见类型转换示例
字符串处理:
List<String> words = Arrays.asList("hello", "world");
List<String> upperCase = words.stream()
.map(String::toUpperCase)
.collect(Collectors.toList()); // ["HELLO", "WORLD"]
数值映射:
立即学习“Java免费学习笔记(深入)”;
List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
List<Integer> squares = numbers.stream()
.map(n -> n * n)
.collect(Collectors.toList()); // [1, 4, 9, 16]
对象字段提取(DTO 转换):
class User { String name; int age; public User(String name, int age) { this.name = name; this.age = age; } }
List<User> users = Arrays.asList(new User("Alice", 25), new User("Bob", 30));
<p>List<String> names = users.stream()
.map(User::getName) // 方法引用
.collect(Collectors.toList()); // ["Alice", "Bob"]</p><p>List<Integer> ages = users.stream()
.map(u -> u.getAge() + 1) // Lambda 表达式,年龄加 1
.collect(Collectors.toList()); // [26, 31]
注意事项与避坑点
- map 不支持“一对多”或“过滤”:需用 flatMap 实现展开,用 filter 做筛选
- 避免在 map 中做副作用操作(如修改外部变量、IO、数据库调用),违背函数式设计原则
- 链式调用时注意顺序:map 后可接 filter、sorted、collect 等,但 map 本身不终止流
- 泛型推导有时会失败,必要时显式指定 lambda 参数类型,例如
.map((String s) -> s.length())
与 flatMap 的关键区别
map 是“一对一”,flatMap 是“一对多再扁平化”。例如把字符串列表转成字符流:
-
list.stream().map(s -> s.split(""))→ 得到Stream<String[]> -
list.stream().flatMap(s -> Arrays.stream(s.split("")))→ 得到Stream<String>(所有字符合并为单层流)


















