Java基础之Java8中map和flatMap的使用

Java基础之Java8中map和flatMap的使用

一、介绍

首先,看下map和flatMap的官方文档说明

  1. map

在这里插入图片描述

  1. flatMap

在这里插入图片描述
其实单纯的看api说明还是比较抽象,下面我将以几个实战例子来帮助我们理解。然后再回过头来看它的说明,就会有一种恍然大悟的感觉。

二、使用

  1. map示例

字母大小写

    public static void main(String[] args) throws Exception {
        // 将集合中的所有的小写字母转为大写字母
        List<String> list = new ArrayList<>();
        list.add("hello");
        list.add("world");
        list.add("java");
        list.add("python");
        List<String> result = list.stream().map(String::toUpperCase).collect(Collectors.toList());
        System.out.println(result);
    }

输出结果如下:

[HELLO, WORLD, JAVA, PYTHON]

平方数


    public static void main(String[] args) throws Exception {
        // 求集合中每个元素的平方数
        List<Integer> nums = Arrays.asList(1, 2, 3, 4);
        List<Integer> result = nums.stream().map(n -> n * n).collect(Collectors.toList());
        System.out.println(result);
    }

输出结果如下:

[1, 4, 9, 16]

从上面例子可以看出,map 生成的是个 1:1 映射,每个输入元素,都按照规则转换成为另外一个元素。还有一些场景,是一对多映射关系的,这时需要 flatMap。

  1. flatMap示例

单词提取

    public static void main(String[] args) throws Exception {
        // 将集合中的字符串中单词提取出来,不考虑特殊字符
        List<String> words = Arrays.asList("hello c++", "hello java", "hello python");
        List<String> result = words.stream()
                // 将单词按照空格切合,返回Stream<String[]>类型的数据
                .map(word -> word.split(" "))
                // 将Stream<String[]>转换为Stream<String>
                .flatMap(Arrays::stream)
                // 去重
                .distinct()
                .collect(Collectors.toList());
        System.out.println(result);
    }

输出结果如下:

[hello, c++, java, python]

元素抽取

public class Main {

    public static void main(String[] args) throws Exception {
        // 初始化测试数据
        List<String> hobby1 = Arrays.asList("java", "c", "音乐");
        List<String> hobby2 = Arrays.asList("c++", "c", "游戏");
        User user1 = new User(1, "张三", hobby1);
        User user2 = new User(2, "李四", hobby2);
        ArrayList<User> users = new ArrayList<>();
        users.add(user1);
        users.add(user2);

        // 将集合中每个用户的爱好进行计算,取并集
        List<String> result = users.stream()
                .map(user -> user.hobby)
                .flatMap(Collection::stream)
                .distinct()
                .collect(Collectors.toList());
        System.out.println(result);
    }

    static class User {
        int id;
        String name;
        List<String> hobby;

        public User(int id, String name, List<String> hobby) {
            this.id = id;
            this.name = name;
            this.hobby = hobby;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            User user = (User) o;
            return id == user.id &&
                    Objects.equals(name, user.name);
        }

        @Override
        public int hashCode() {
            return Objects.hash(id, name);
        }

        @Override
        public String toString() {
            return "User{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
}

输入结果如下:

[java, c, 音乐, c++, 游戏]

flatMap 把 input Stream 中的层级结构扁平化,就是将最底层元素抽出来放到一起,最终 output 的新 Stream 里面已经没有 List 了,都是直接的数字.

三、map和flatMap的原理图示

  1. map原理图

在这里插入图片描述

对于Stream中包含的元素使用给定的转换函数进行转换操作,新生成的Stream只包含转换生成的元素。这个方法有三个对于原始类型的变种方法,分别是:mapToInt,mapToLong和mapToDouble。这三个方法也比较好理解,比如mapToInt就是把原始Stream转换成一个新的Stream,这个新生成的Stream中的元素都是int类型。之所以会有这样三个变种方法,可以免除自动装箱/拆箱的额外消耗。

  1. flatMap原理图

在这里插入图片描述

和map类似,不同的是其每个元素转换得到的是Stream对象,会把子Stream中的元素压缩到父集合中

发布了158 篇原创文章 · 获赞 147 · 访问量 27万+

猜你喜欢

转载自blog.csdn.net/weixin_39723544/article/details/97976604