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);