java8 map flatmap

构建对象

class User{
 private   String addr
}

将多个User集合中的addr按照;分割合并成一个字符串list

 List<User> uList = Lists.newArrayList();
 User u1 = new User();
 u1.setAddr("a1;a2;a3;a4;a5");
 
 User u2 = new User();
 u2.setAddr("b1;b2;b3;b4;b5");
 
 uList.add(a);
 uList.add(b);
 
 List<String> addrList = uList.stream().map(x -> x.getAddr()).flatMap(x->Arrays.stream(x.split(";"))).collect(Collectors.toList());
 //或者
 List<String> ridStrList = uList.stream().map(x -> x.getAddr()).map(x -> x.split(";")).flatMap(Arrays::stream).collect(Collectors.toList());
 System.out.println(addrList);

说明:
flatMap的用法和含义住要通过一个案例来讲解,
案例:对给定单词列表 ["Hello","World"],你想返回列表["H","e","l","o","W","r","d"]
第一种方式

 String[] words = new String[]{"Hello","World"};
 List<String[]> a = Arrays.stream(words)
  .map(word -> word.split(""))
  .distinct()
  .collect(toList());
 a.forEach(System.out::print);

代码输出为:[Ljava.lang.String;@12edcd21[Ljava.lang.String;@34c45dca (返回一个包含两个String[]的list)
这个实现方式是由问题的,传递给map方法的lambda为每个单词生成了一个String[](String列表)。因此,map返回的流实际上是Stream<String[]> 类型的。你真正想要的是用Stream<String>来表示一个字符串。
下方图是上方代码stream的运行流程

第二种方式:flatMap(对流扁平化处理)

String[] words = new String[]{"Hello","World"};
 List<String> a = Arrays.stream(words)
  .map(word -> word.split(""))
  .flatMap(Arrays::stream)
  .distinct()
  .collect(toList());
 a.forEach(System.out::print);

结果输出:HeloWrd
使用flatMap方法的效果是,各个数组并不是分别映射一个流,而是映射成流的内容,所有使用map(Array::stream)时生成的单个流被合并起来,即扁平化为一个流。
下图是运用flatMap的stream运行流程,

map
map比较简单,可以抽取列表元素的某个属性形成新的列表,但是无法对更深层的属性做提取
map能够直接操作list中的每个对象

代码示例:

List<Integer> integers = new ArrayList<>();
//添加数据略
integers.stream.map(i -> i + 1).foreach(System.out::println);

 List<User> users = new ArrayList<>();
 User user = new User();
 user.setAddr("12345");
 users.add(user);

 List<String> aa = users.stream().map(data -> {
     return data.getAddr();
 }).collect(Collectors.toList());
 System.out.println(aa);

flatMap
可以操作更深层的数据

代码示例:

 List<List<Integer>> outer = new ArrayList<>();
 List<Integer> inner1 = new ArrayList<>();
 inner1.add(1);
 List<Integer> inner2 = new ArrayList<>();
 inner2.add(2);
 List<Integer> inner3 = new ArrayList<>();
 inner3.add(3);
 List<Integer> inner4 = new ArrayList<>();
 inner4.add(4);
 List<Integer> inner5 = new ArrayList<>();
 inner5.add(5);
 outer.add(inner1);
 outer.add(inner2);
 outer.add(inner3);
 outer.add(inner4);
 outer.add(inner5);
 List<Integer> result = outer.stream().flatMap(inner -> inner.stream().map(i -> i + 1)).collect(Collectors.toList());
 System.out.println(result);

Stream.flatMap,正如它的名称所猜测的,是map和一个flat行动。这意味着您首先对元素应用一个函数,然后将其扁平化。Stream.map只对流应用函数,而不对流进行平坦处理。为了理解什么是扁平化,考虑一个像[[1,2,3],[4,5,6],[7,8,9]]这样的具有“两个层次”的结构。 扁平化意味着将其转化为“一个一级”结构:[1,2,3,4,5,6,7,8,9]。注意:flatmap里面处理的是流stream。而map处理的是元素对象。这个需要注意。如下所示:

 List<User> users = new ArrayList<>();
 User user = new User();
 user.setAddr("12345");
 users.add(user);
 List<String> aa = users.stream().flatMap(data -> Stream.of(data.getAddr().split(""))).collect(Collectors.toList());
 System.out.println(aa);
郭慕荣博客园
原文地址:https://www.cnblogs.com/jelly12345/p/15078950.html