Stream流中的Map与flatMap的区别

0. 先说结论

  1. map的作用:是将输入一种类型,转化为另一种类型,通俗来说:就是将输入类型变成另一个类型。
  2. flatMap的作用:是扁平化的,比如有对象List<List<User>> userLists, 这属于套娃现象,而最终我们只想得到List<User> userList对象,即将多维集合,变成一个集合,相当于压缩,俗称扁平化。

1. 需求

  1. 之前在做开发的时候,遇到如下需求:
    List<Room>对象,需要获取到List<String> peopleNameList对象

    // 解释:一个房间有自己的房间号,里面有一堆人,每个人都有面子
    	@Data
        @AllArgsConstructor
        @NoArgsConstructor
        static class Room {
            private int number;
            private List<People> peopleList;
    
    
            @Data
            @NoArgsConstructor
            @AllArgsConstructor
            static class People {
                private String name;
            }
        }
    

2. 解决方案

1. 使用Map方法

  1. 如下:如果只是使用普通的map方法且里面是直接getPeopleList()方法,则得到的是 List<List<Room.People>> collect 对象。

    public class demo {
        public static void main(String[] args) {
            final List<Room> roomList = initRoom();
            List<List<Room.People>> collect = roomList.stream()
                    .map(Room::getPeopleList)
                    .collect(Collectors.toList());
        }
    }
    
  2. 通常遇到这情况,一般人解决就是在遍历一次,如下:

    public class demo {
        public static void main(String[] args) {
            final List<Room> roomList = initRoom();
            List<List<Room.People>> collect = roomList.stream()
                    .map(Room::getPeopleList)
                    .collect(Collectors.toList());
            // 1.先new ArrayList<>() 准备存储String字符串
            List<String> peopleNameList = new ArrayList<>();
            // 2. 这里就得套两层的foreach了
            // 因为初始化是List<List<T>>对象
            // 第一次foreach中peopleList 是List<Room.People>对象
            collect.forEach(peopleList -> {
             	// 第二次foreach中people 是People对象
                peopleList.forEach(people -> {
                    peopleNameList.add(people.getName());
                });
            });
        }
    
  3. 而有的人可能会在上面的基础上,再进一步优化为如下:

    public class demo {
        public static void main(String[] args) {
            final List<Room> roomList = initRoom();
    
            List<String> peopleNameList = new ArrayList<>();
    		// 直接一直使用stream流的foreach
    		// 虽然是比上面代码优雅多了,但两个foreach,怎么看都不舒服
            roomList.stream().forEach(room -> {
                room.getPeopleList().forEach(people -> {
                    peopleNameList.add(people.getName());
                });
            });
        }
    }
    

2. 使用flatMap解决

  1. flatMap就是用于多层结构的扁平化,如下:

    public class demo {
        public static void main(String[] args) {
            final List<Room> roomList = initRoom();
    
            List<String> peopleNameList = roomList.stream()
                    .map(Room::getPeopleList)
                    .flatMap(Collection::stream)
                    .map(Room.People::getName)
                    .collect(Collectors.toList());
        }
    }
    

    在这里插入图片描述

3. 完整代码

  1. 代码如下:

    public class demo {
            public static void main(String[] args) {
                final List<Room> roomList = initRoom();
    
                // Map方法
                List<String> peopleNameList = new ArrayList<>();
                
                roomList.stream().forEach(room -> {
                    room.getPeopleList().forEach(people -> {
                        peopleNameList.add(people.getName());
                    });
                });
                
                // flatMap 方法
                List<String> peopleNameList2 = roomList.stream()
                        .map(Room::getPeopleList)
                        .flatMap(Collection::stream)
                        .map(Room.People::getName)
                        .collect(Collectors.toList());
            }
    
        // 初始化10条数据
        private static List<Room> initRoom() {
            return IntStream.range(1, 11)
                    .mapToObj(num -> new Room(num, Arrays.asList(new Room.People("name:" + num), new Room.People("name:" + 10 * num))))
                    .collect(Collectors.toList());
        }
    
        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        static class Room {
            private int number;
            private List<People> peopleList;
    
    
            @Data
            @NoArgsConstructor
            @AllArgsConstructor
            static class People {
                private String name;
            }
        }
    }
    
  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值