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

r囧r小猫 2021-11-14 15:14 489阅读 0赞

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

一、介绍

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

  1. map

在这里插入图片描述

  1. flatMap

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

二、使用

  1. map示例

字母大小写

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

输出结果如下:

  1. [HELLO, WORLD, JAVA, PYTHON]

平方数

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

输出结果如下:

  1. [1, 4, 9, 16]

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

  1. flatMap示例

单词提取

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

输出结果如下:

  1. [hello, c++, java, python]

元素抽取

  1. public class Main {
  2. public static void main(String[] args) throws Exception {
  3. // 初始化测试数据
  4. List<String> hobby1 = Arrays.asList("java", "c", "音乐");
  5. List<String> hobby2 = Arrays.asList("c++", "c", "游戏");
  6. User user1 = new User(1, "张三", hobby1);
  7. User user2 = new User(2, "李四", hobby2);
  8. ArrayList<User> users = new ArrayList<>();
  9. users.add(user1);
  10. users.add(user2);
  11. // 将集合中每个用户的爱好进行计算,取并集
  12. List<String> result = users.stream()
  13. .map(user -> user.hobby)
  14. .flatMap(Collection::stream)
  15. .distinct()
  16. .collect(Collectors.toList());
  17. System.out.println(result);
  18. }
  19. static class User {
  20. int id;
  21. String name;
  22. List<String> hobby;
  23. public User(int id, String name, List<String> hobby) {
  24. this.id = id;
  25. this.name = name;
  26. this.hobby = hobby;
  27. }
  28. @Override
  29. public boolean equals(Object o) {
  30. if (this == o) return true;
  31. if (o == null || getClass() != o.getClass()) return false;
  32. User user = (User) o;
  33. return id == user.id &&
  34. Objects.equals(name, user.name);
  35. }
  36. @Override
  37. public int hashCode() {
  38. return Objects.hash(id, name);
  39. }
  40. @Override
  41. public String toString() {
  42. return "User{" +
  43. "id=" + id +
  44. ", name='" + name + '\'' +
  45. '}';
  46. }
  47. }
  48. }

输入结果如下:

  1. [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中的元素压缩到父集合中

发表评论

表情:
评论列表 (有 0 条评论,489人围观)

还没有评论,来说两句吧...

相关阅读