Java Stream映射
在Java Stream API中,映射(Mapping)是一种常用的转换操作,它允许我们将流中的元素从一种形式转换为另一种形式。映射操作通过应用一个函数到流的每个元素上,生成一个包含转换结果的新流。这种转换能力使得数据处理变得异常灵活和强大。
映射操作的基础
Stream API提供了多种映射方法,最基础的是map()
方法。让我们先了解什么是映射操作:
映射定义
映射是一种将流中的每个元素转换为另一种形式的操作,转换后的元素会形成一个新的流。
map方法
map()
方法接收一个函数作为参数,该函数会被应用到流中的每个元素上,然后返回一个包含转换结果的新流。
基本语法
<R> Stream<R> map(Function<? super T, ? extends R> mapper)
简单示例
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// 将每个名字转换为大写
List<String> uppercaseNames = names.stream()
.map(name -> name.toUpperCase())
.collect(Collectors.toList());
System.out.println("原始名字: " + names);
System.out.println("转换后的名字: " + uppercaseNames);
输出:
原始名字: [Alice, Bob, Charlie]
转换后的名字: [ALICE, BOB, CHARLIE]
特殊映射方法
除了基本的map()
方法外,Stream API还提供了几种特殊的映射方法,用于处理原始类型(primitive types)或者更复杂的映射场景。
1. mapToInt、mapToLong和mapToDouble
这些方法用于将对象流映射为原始类型流,避免了自动装箱/拆箱的性能开销。
List<String> numbers = Arrays.asList("1", "2", "3", "4", "5");
// 将字符串转换为整数并计算总和
int sum = numbers.stream()
.mapToInt(Integer::parseInt)
.sum();
System.out.println("字符串数字之和: " + sum);
输出:
字符串数字之和: 15
2. flatMap方法
flatMap()
方法用于处理嵌套结构,它将流中的每个元素映射为一个流,然后将所有生成的流连接成一个流。
提示
flatMap()
非常适合处理嵌套集合或者需要将一对多映射扁平化的场景。
基本语法
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)
示例:处理嵌套列表
List<List<Integer>> nestedNumbers = Arrays.asList(
Arrays.asList(1, 2, 3),
Arrays.asList(4, 5, 6),
Arrays.asList(7, 8, 9)
);
// 使用flatMap将嵌套列表扁平化为单个流
List<Integer> flattenedNumbers = nestedNumbers.stream()
.flatMap(list -> list.stream())
.collect(Collectors.toList());
System.out.println("嵌套列表: " + nestedNumbers);
System.out.println("扁平化后的列表: " + flattenedNumbers);
输出:
嵌套列表: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
扁平化后的列表: [1, 2, 3, 4, 5, 6, 7, 8, 9]
映射操作的实际应用场景
让我们看一些映射操作在实际应用中的例子:
场景1:处理对象列表
假设我们有一个Person
类,现在需要从一个人员列表中提取所 有人的名字。
class Person {
private String name;
private int age;
// 构造函数、getters和setters
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
// 使用map从Person对象列表中提取名字
List<Person> persons = Arrays.asList(
new Person("Alice", 25),
new Person("Bob", 30),
new Person("Charlie", 35)
);
List<String> names = persons.stream()
.map(Person::getName)
.collect(Collectors.toList());
System.out.println("人员名单: " + names);
输出:
人员名单: [Alice, Bob, Charlie]
场景2:文件处理
假设我们有一个文本文件,每行包含一个逗号分隔的单词列表,我们想要提取所有的唯一单词。
// 假设我们已经有了文件的行列表
List<String> lines = Arrays.asList(
"hello,world,java",
"stream,map,flatMap",
"hello,stream,example"
);
// 使用flatMap将每行拆分为单词,然后收集所有唯一单词
Set<String> uniqueWords = lines.stream()
.flatMap(line -> Arrays.stream(line.split(",")))
.collect(Collectors.toSet());
System.out.println("唯一单词: " + uniqueWords);
输出:
唯一单词: [world, example, flatMap, map, java, hello, stream]