Java Stream.map()方法详解

后端 潘老师 6个月前 (10-29) 154 ℃ (0) 扫码查看

Java 8的Stream.map()操作将流中的元素从一种类型转换为另一种类型。在map()操作完成后,对于当前流中的每个类型为X的元素,都会创建一个类型为Y的新对象,并将其放入新的流中。

Stream —> map() operation —> Stream

1.什么时候使用Stream.map()操作?

map()操作特别适用于数据操作和转换任务。考虑几个可能的用例以了解何时可以使用map():

  • 数据库迁移期间,我们可能希望将数据从旧模式转换为新模式。使用map(),我们可以定义实体之间的字段映射来复制它们的值。
  • 从不同的源读取数据并转换为一个标准格式,然后以标准方式处理之前,可以使用map()进行数据清理。
  • 在MVC模式中,我们可以使用map()将JPA实体数据复制到VO对象中,以便渲染用户视图。

在下面的示例中,我们使用map()从Stream转换为Stream

// 快速指引
//从 Stream<PersonEntity> 转换为 Stream<PersonVO> 并收集到一个新的 List 中 
List<PersonEntity> personEntityList = ...;  // PersonEntity集合
List<PersonVO> personVoList = personEntityList.stream()
    .map(e -> createVoFromEntity(e))
    .toList();
//在map映射操作中调用的实用函数
public static PersonVO createVoFromEntity(PersonEntity entity) { ... }

2.流map()方法

2.1 方法语法

<R> Stream<R> map(Function<? super T,? extends R> mapper)
  • 流map()方法有以下语法。R表示新流的元素类型。
  • mapper是一个非干扰的、无状态函数,应用于每个元素,产生一个新值的流。
  • 该方法返回一个类型为R的新流。

2.2 描述

  • map()是一种中间操作,它返回一个新的Stream作为返回值。
  • map()操作采用一个Function,它对输入流中的每个值进行调用,并产生一个结果值发送到输出流。
  • 用于转换的映射函数是一个无状态函数(不存储先前处理的对象的的信息)并且只返回单个值。
  • 当想把Stream X转换为Stream Y时使用map()方法。
  • 映射流在内容被放入新的输出流后关闭。
  • map()操作不会像flatMap()操作那样使流扁平化。

3.流map()示例

让我们看几个更多的例子以更好地理解。

示例1:将字符串流转换为整数流

在这个例子中,我们将把Stream转换为Stream。这里,映射函数Integer::valueOf()每次从流中取出一个字符串并将其转换为整数。

然后把整数放入另一个流中,然后使用Collectors.toList()收集它。

List<String> listOfStrings = Arrays.asList("1", "2", "3", "4", "5");
List<Integer> listOfIntegers = listOfStrings.stream()
        .map(Integer::valueOf)
        .collect(Collectors.toList());
System.out.println(listOfIntegers);

程序输出。

[1, 2, 3, 4, 5]

示例2:在所有员工中查找所有不同的薪水

Java示例,用于查找一组员工中所有可能的不同的薪水。

List<Employee> employeesList = Arrays.asList(
                                    new Employee(1, "Alex", 100),
                                    new Employee(2, "Brian", 100),
                                    new Employee(3, "Charles", 200),
                                    new Employee(4, "David", 200),
                                    new Employee(5, "Edward", 300),
                                    new Employee(6, "Frank", 300)
                                );
List<Double> distinctSalaries = employeesList.stream()
                        .map( e -> e.getSalary() )
                        .distinct()
                        .collect(Collectors.toList());
System.out.println(distinctSalaries);

程序输出。

[100.0, 200.0, 300.0]

4. 整数流、长整型流或双精度浮点型流【特殊情况】

流接口还有另外三个类似的方法用于数值类型,通常用于执行数值计算或转换。这些方法分别产生IntStream、LongStream和DoubleStream。

IntStream mapToInt(ToIntFunction<? super T> mapper)
LongStream mapToLong(ToLongFunction<? super T> mapper)
DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper)

使用这些类的优点是它们提供了方便的方法来处理流元素并执行数学/聚合操作,而不需要装箱和拆箱的开销。在下面的示例中,我们有一个代表字符串的考试分数列表,我们想要计算平均分数:

List<String> scoresAsString = Arrays.asList("85", "92", "78", "90", "88");
double averageScore = scoresAsString.stream()
  .mapToInt(Integer::parseInt)    // 使用mapToInt()将string 转换为integer 
  .average()        // 计算integer平均值
  .orElse(0.0);    // 如果没有scores则默认值为0.0
System.out.println("Average score: " + averageScore);

版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/back/10472.html
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】