跳转到内容

Java Stream映射

来自代码酷

Java Stream映射[编辑 | 编辑源代码]

Java Stream映射(Stream Mapping)是Java Stream API中的核心操作之一,允许开发者对Stream中的元素进行转换或提取数据。映射操作通常使用`map()`和`flatMap()`方法,能够将一种类型的流转换为另一种类型,或者将嵌套结构扁平化。

简介[编辑 | 编辑源代码]

在Java Stream中,映射操作允许对流的每个元素应用一个函数,生成一个新的流。例如,可以将一个`Stream<String>`转换为`Stream<Integer>`,或者从一个对象流中提取某个属性。

映射操作主要有两种:

  • `map()`:对每个元素应用一个函数,返回转换后的流。
  • `flatMap()`:将嵌套的流结构(如`Stream<Stream<T>>`)扁平化为单个流。

map() 方法[编辑 | 编辑源代码]

`map()`方法接收一个`Function<T, R>`参数,将类型`T`的元素转换为类型`R`的元素。

基本语法[编辑 | 编辑源代码]

<R> Stream<R> map(Function<? super T, ? extends R> mapper)

示例:转换字符串为大写[编辑 | 编辑源代码]

List<String> names = List.of("alice", "bob", "charlie");
List<String> upperCaseNames = names.stream()
    .map(String::toUpperCase)
    .toList();

System.out.println(upperCaseNames); // 输出: [ALICE, BOB, CHARLIE]

示例:提取对象属性[编辑 | 编辑源代码]

class Person {
    String name;
    int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    String getName() { return name; }
}

List<Person> people = List.of(
    new Person("Alice", 25),
    new Person("Bob", 30)
);

List<String> names = people.stream()
    .map(Person::getName)
    .toList();

System.out.println(names); // 输出: [Alice, Bob]

flatMap() 方法[编辑 | 编辑源代码]

`flatMap()`用于处理嵌套流结构,将多个流合并为一个流。

基本语法[编辑 | 编辑源代码]

<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)

示例:扁平化嵌套列表[编辑 | 编辑源代码]

List<List<Integer>> nestedNumbers = List.of(
    List.of(1, 2),
    List.of(3, 4),
    List.of(5, 6)
);

List<Integer> flattenedNumbers = nestedNumbers.stream()
    .flatMap(List::stream)
    .toList();

System.out.println(flattenedNumbers); // 输出: [1, 2, 3, 4, 5, 6]

示例:拆分字符串为字符流[编辑 | 编辑源代码]

List<String> words = List.of("hello", "world");
List<String> letters = words.stream()
    .flatMap(word -> Arrays.stream(word.split("")))
    .toList();

System.out.println(letters); // 输出: [h, e, l, l, o, w, o, r, l, d]

实际应用案例[编辑 | 编辑源代码]

案例1:数据清洗与转换[编辑 | 编辑源代码]

假设有一个CSV文件,每行包含多个以逗号分隔的数字,需要计算所有数字的平均值。

List<String> csvLines = List.of("1,2,3", "4,5,6", "7,8,9");

double average = csvLines.stream()
    .flatMap(line -> Arrays.stream(line.split(",")))
    .mapToDouble(Double::parseDouble)
    .average()
    .orElse(0.0);

System.out.println("平均值: " + average); // 输出: 平均值: 5.0

案例2:多级数据处理[编辑 | 编辑源代码]

从多个订单中提取所有商品名称:

class Order {
    List<String> items;

    Order(List<String> items) {
        this.items = items;
    }

    Stream<String> getItemsStream() {
        return items.stream();
    }
}

List<Order> orders = List.of(
    new Order(List.of("苹果", "香蕉")),
    new Order(List.of("橙子", "葡萄"))
);

List<String> allItems = orders.stream()
    .flatMap(Order::getItemsStream)
    .toList();

System.out.println(allItems); // 输出: [苹果, 香蕉, 橙子, 葡萄]

性能考虑[编辑 | 编辑源代码]

  • `map()`和`flatMap()`都是惰性操作,只有在终端操作(如`collect()`或`forEach()`)调用时才会执行。
  • `flatMap()`可能比`map()`更消耗资源,因为它需要合并多个流。

总结[编辑 | 编辑源代码]

Java Stream映射操作(`map()`和`flatMap()`)提供了灵活的数据转换能力:

  • 使用`map()`进行简单的一对一转换。
  • 使用`flatMap()`处理嵌套结构或合并多个流。

graph LR A[原始Stream] --> B[map转换] A --> C[flatMap扁平化] B --> D[新Stream] C --> D

另请参阅[编辑 | 编辑源代码]