Java8 Map和flatMap实战

一个例子理解这三种方法。
一、对于一张单 词表,如何返回一张列表,列出里面各不相同的字符呢?例如,给定单词列表
[” Hello ”,W orld ”],你想要返回列表[ "H","e","l","o","W","r","d"   ], 你可能会认为很容易,你可以把每个单词映射成一张字符表,然后调用distinct 来去除 重复的字符。
第一个版本可能是这样的:
words.stream() 
.map(word ->word.split ("")) 
.distinct() 
.collect(toList()) ;
这个方法的问题在于,传递给 map 方法的 Lambda 为每个单词返回了一个 String[]( S tring
列表)  因此, map 返回的流实际上是 Stream >类型 你真正想要的是用 Stream< String >来表示一个字符流。如图说明了这个问题:

幸好可以用 flatMap来解决这个问题!让我们一步步看看怎么解决它。

1. 尝试使用 map 和 Arrays. stream()
首先,你需要一个字符流,而不是数组流。有一个叫作 Arrays. stream ()的方法可以接受
一个数组并产生一个流,例如:
String[] arrayOfWords = {"Goodbye","World"}; 
Stream streamOfwords = Arrays.stream(arrayOfWords);
把它用在前面的那个流水线里,看看会发生什么:
words.stream () 
.map(word ->word.split(""))
.map(Arrays::stream) 
.distinct() 
.collect(toList());
当前的解决方案仍然搞不定!这是因为,你现在得到的是一个流的列表(更准确地说是
Stream )!的确,你先是把每个单词转换成一个字母数组,然后把每个数组变成了一
个独立的流。
2. 使用 flatMap
你可以像下面这样使用 flatMap 来解决这个问题:
List uniqueCharacters = 
words.stream() 
.map(w -> w.split("")) 
.flatMap(Arrays::stream)
.distinct()
.cllect(Collectors.toList());
使用 flatMap 方法的效果是,各个数组并不是分别映射成一个流,而是映射成流的内容。所
有使用 map(Arrays::stream )时生成的单个流都被合并起来,即扁平化为一个流。下图 说明了
使用 flatMap 方法的效果。
一言以蔽之, flatmap 方法让你把一个流中的每个值都换成另一个流,然后把所有的流连接
起来成为 一个流。

你可能感兴趣的:(java)