Java Stream map
最后修改于 2025 年 5 月 25 日
在本文中,我们将探讨如何有效地在 Java 流上执行 map 操作,利用函数式编程原则来高效地转换数据。
Java Stream 是一个来自数据源的元素序列,该数据源支持聚合操作。流不存储元素——相反,它们按需计算结果,这使得它们特别适用于处理大型数据集。可以从集合、数组或 I/O 资源等源使用元素,允许开发人员动态地处理数据。
流聚合操作的功能类似于 SQL 查询,使开发人员能够直接在数据流上执行过滤、映射、归约、匹配、搜索和排序。 通过利用流链接,可以按顺序应用多个操作,从而提高代码的可读性和效率。 与依赖于外部迭代的传统集合不同,流旨在使用内部迭代,从而优化执行控制和性能。
Stream Map 操作
map 方法是 Java Streams 中的一个中间操作,它允许将流元素转换为新形式,而无需修改原始源。 此方法将一个函数应用于每个元素,生成一个具有转换值的新流。
map 方法接受一个 lambda 函数作为参数,并单独处理每个元素,应用函数中定义的转换。 这使得它非常适合数据转换,例如
- 修改流中的对象属性。
- 从复杂的数据结构中提取特定属性。
- 将一种数据类型转换为另一种数据类型(例如,String 到 Integer)。
使用 map 方法的好处包括
- 不可变处理:原始数据保持不变。
- 函数式方法:减少转换的样板代码。
- 性能优化:在大数据集上高效工作。
- 无缝集成:可以与其他流操作(如 filter 和 reduce)结合使用。
map 方法是将转换应用于 Java 流中的数据的强大工具,使其成为函数式编程和现代 Java 开发的必备工具。
映射算术运算
在第一个示例中,我们映射一个值序列上的算术运算。
void main() {
var nums = IntStream.of(1, 2, 3, 4, 5, 6, 7, 8);
var squares = nums.map(e -> e * e).toArray();
System.out.println(Arrays.toString(squares));
}
在该示例中,我们创建一个整数流。 使用 map 方法,我们将算术运算应用于这些值,然后将它们转换为一个数组。
将字符串转换为用户
下一个示例演示如何将字符串流转换为自定义对象的流。
void main() throws IOException {
String data = """
John,Doe
Jane,Smith
Alice,Johnson
Bob,Brown
""";
var users = data.lines()
.map(line -> line.split(",", 2))
.map(fields -> new User(fields[0].trim(), fields[1].trim()))
.toList();
System.out.println(users);
}
record User(String firstName, String lastName) {
}
我们创建一个 User 类并将字符串映射到该类的实例。 每个字符串都被拆分为名字和姓氏,然后用于创建一个新的 User 对象。 这种方法允许我们将原始数据转换为结构化对象,以便于在我们的应用程序中进行操作和处理。
mapToInt 方法
mapToInt 方法是 map 方法的一个专门版本,它专门将流的元素映射到原始 int 值。 当处理需要转换为整数的对象流时,此方法特别有用,例如从对象中提取数字属性或对流元素执行算术运算时。
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int sumEvenNumbers = numbers.stream()
.mapToInt(Integer::intValue) // Convert Integer objects to primitive int
.filter(n -> n % 2 == 0) // Keep only even numbers
.sum(); // Compute sum
System.out.println("Sum of even numbers: " + sumEvenNumbers);
该示例演示如何使用 mapToInt 方法将 Integer 对象流转换为原始 int 值的流。 这种转换允许进行有效的算术运算,例如过滤偶数并计算它们的总和。 当处理需要转换为原始类型的对象集合以进行数值计算时,mapToInt 方法特别有用。
映射自定义方法
在下一个示例中,我们将一个自定义方法映射到一个字符串流。
void main() {
var words = Stream.of("cardinal", "pen", "coin", "globe");
words.map(this::capitalize).forEach(System.out::println);
}
String capitalize(String word) {
word = word.substring(0, 1).toUpperCase() + word.substring(1).toLowerCase();
return word;
}
该示例将流中的每个单词大写。
从 CSV 文件读取
我们可以使用 map 方法将值从 CSV 文件读取到列表中。
2,3,5,6,1,0 9,5,6,3,2,1
我们在 numbers.csv 文件中有这些值。
void main() throws IOException {
int sum = Files.lines(Path.of("numbers.csv")) // Stream file lines directly
.mapToInt(line -> Arrays.stream(line.split(","))
.mapToInt(Integer::parseInt)
.sum()) // Convert and sum each line
.sum(); // Total sum
System.out.println("Total sum: " + sum);
}
首先,我们将 CSV 文件读取到字符串列表中。 然后我们从该列表创建一个流,并应用映射方法来获得最终的整数列表。
var lines = Files.readAllLines(Path.of("src/resources/numbers.csv"));
使用 Files.readAllLines,我们将文件的所有行读取到字符串列表中。
int sum = Files.lines(Path.of("numbers.csv")) // Stream file lines directly
.mapToInt(line -> Arrays.stream(line.split(","))
.mapToInt(Integer::parseInt)
.sum()) // Convert and sum each line
我们从文件行创建一个流。 每行都用逗号分割,并且每个结果字符串都使用 Integer::parseInt 转换为整数。 mapToInt 方法用于将字符串流转换为整数流。 然后应用 sum 方法来计算流中所有整数的总和。 这种方法允许有效地处理 CSV 数据,将其转换为适合进一步分析或计算的格式。
$ java Main.java [2, 3, 5, 6, 1, 0, 9, 5, 6, 3, 2, 1]
提取特定属性
map 方法也可用于提取流中对象的特定属性。 当处理复杂对象的集合时,这特别有用,允许你专注于相关数据,而无需操作整个对象结构。
void main() {
var users = List.of(new User("Peter", "programmer"),
new User("Jane", "accountant"), new User("Robert", "teacher"),
new User("Milan", "programmer"), new User("Jane", "designer"));
var userNames = users.stream().map(User::name).sorted().toList();
System.out.println(userNames);
var occupations = users.stream().map(User::occupation)
.sorted(Comparator.reverseOrder()).distinct().toList();
System.out.println(occupations);
}
record User(String name, String occupation) {
}
在此示例中,我们有一个 User 对象列表。 我们使用 map 方法从每个用户中提取 name 和 occupation 属性。 然后将 sorted 方法应用于结果流,以按字母顺序对名称进行排序,并按相反的顺序对职业进行排序。 使用 distinct 方法来确保最终列表中仅包含唯一的职业。 最后,我们使用 collect 方法将结果收集到列表中。
$ java Main.java [Jane, Jane, Milan, Peter, Robert] [teacher, programmer, designer, accountant]
来源
在本文中,我们使用了 Java Stream 映射操作。
作者
列出所有Java教程。