Java Stream 中的 Map与flatMap 函数

目录

map 函数的作用是映射, 或者说转换, 把对象A 转换到对象B, 可以切换类型。
flatMap 函数的作用是先执行 map操作, 然后平铺。

示例

下面看示例1.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package com.example;

import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamTest {

    public static void main(String[] args) {

        var list1 = Stream.of(1, 2, 3, 4, 5).map(i -> i * 2).collect(Collectors.toList());
        System.out.println(list1); // [2, 4, 6, 8, 10]

        var list2 = Stream.of(new int[] { 1, 2 }, new int[] { 3, 4 }, new int[] { 5 })
                .flatMap(array -> Arrays.stream(array).boxed()).map(i -> i * 2).collect(Collectors.toList());
        System.out.println(list2); // [2, 4, 6, 8, 10]
    }

}

list1 演示了 map 对整形数字的用法, 这里并没有切换数字的类型。 list2 看起来稍微复杂一些,并且在 flatMap 之后, 又使用了一个 map 函数。 此例的 flatMap 的作用是转换 Stream<int[]>Stream<int>

参考阅读: https://stackoverflow.com/a/27888447/11226492
大致翻译一下:

Stream.of(intArray) 将返回一个 Stream<int[]> 类型
Arrays.stream(intArr) 将返回一个 IntStream 类型

下面再来看下示例2

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package com.example;

import java.util.Arrays;
import java.util.Comparator;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

public class StreamTest {

    /**
     * Desk
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Desktop {
        private String type;
        private String color;
        private int width;
        private int height;

        // ...
        // ...
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Dimension {
        private String customString;
        private int width;
        private int height;

        public int area() {
            return width * height;
        }
    }

    public static void main(String[] args) {

        var desks = Arrays.asList(new Desktop("Desk1", "white", 100, 100),
                new Desktop("Desk2", "white", 110, 110),
                new Desktop("Desk3", "black", 120, 120),
                new Desktop("Desk4", "black", 130, 130),
                new Desktop("Desk5", "black", 140, 140));

        var maxArea = desks.stream().map(d -> new Dimension(d.getType(), d.getWidth(), d.getHeight()))
                .max(Comparator.comparingInt(Dimension::area));
        System.out.println(maxArea.get()); // StreamTest.Dimension(customString=Desk5, width=140, height=140)

        var deskArrayList = Arrays.asList(new Desktop[] {
                new Desktop("Desk1", "white", 100, 100),
                new Desktop("Desk2", "white", 110, 110)
                },
                new Desktop[] {
                        new Desktop("Desk3", "black", 120, 120),
                        new Desktop("Desk4", "black", 130, 130),
                },
                new Desktop[] {
                        new Desktop("Desk5", "black", 140, 140)
                });

        maxArea = deskArrayList.stream()
                .flatMap(l -> Stream.of(l).map(d -> new Dimension(d.getType(), d.getWidth(), d.getHeight())))
                .max(Comparator.comparingInt(Dimension::area));
        System.out.println(maxArea.get());  //  StreamTest.Dimension(customString=Desk5, width=140, height=140)

    }

}

有些读者看完代码可能会说 为什么Desktop不直接引用Dimension呢?
因为这是一个示例,还可能因为是Desktop类型是已经入库的,不方便修改的。等等之类的
还有诸如 area 方法为什么不放在 Desktop 中之类的, 大多都是因为这是一个示例。关注点应该是map和flatMap函数的使用和作用。

在求解 maxArea 的地方,可以看到 map 函数把一个Stream<Desktop> 转换成了一个 Stream<Dimension> 类型。

在第二次求解 maxArea 的地方, 可以看到flatMap函数把一个 Stream<Desktop[]> 转换成了一个 Stream<Dimension> 类型。

flatMap函数感觉一般用不着。

其他

扩展阅读:

0%