Java8 FlatMap的使用

给定单词列表[“Hello”,“World”],你想要返回列表[“H”,“e”,“l”, “o”,“W”,“r”,“d”]

你可能首先想到的是:可以把每个单词映射成一张字符表,然后调用distinct来过滤重复的字符。

即:

words.stream() 
 .map(word -> word.split("")) 
 .distinct() 
 .collect(toList());

这个方法的问题在于,传递给map方法的Lambda为每个单词返回了一个String[](String 列表)。因此,map返回的流实际上是Stream<String[]>类型的。你真正想要的是用 Stream 来表示一个字符流,如图:
在这里插入图片描述

  1. 尝试使用mapArrays.stream()

首先,你需要一个字符流,而不是数组流。有一个叫作Arrays.stream()的方法可以接受一个数组并产生一个流,例如:

String[] arrayOfWords = {"Goodbye", "World"}; 

Stream<String> streamOfwords = Arrays.stream(arrayOfWords); 

把它用在前面的那个流水线里,看看会发生什么:

words.stream() 

 .map(word -> word.split("")) //将每个单词转换为由其字母构成的数组

 .map(Arrays::stream)//让每个数组变成一个单独的流

 .distinct() 

 .collect(toList()); 

当前的解决方案仍然搞不定!这是因为,你现在得到的是一个流的列表(更准确地说是Stream)。的确,你先是把每个单词转换成一个字母数组,然后把每个数组变成了一个独立的流。

  1. 使用flatMap

你可以像下面这样使用flatMap来解决这个问题:

List<String> uniqueCharacters = 

 words.stream() 

 .map(w -> w.split("")) //将每个单词转换为由其字母构成的数组

 .flatMap(Arrays::stream) //将各个生成流扁平化为单个流

 .distinct() 

 .collect(Collectors.toList()); 

使用flatMap方法的效果是,各个数组并不是分别映射成一个流,而是映射成流的内容。所有使用map(Arrays::stream)时生成的单个流都被合并起来,即扁平化为一个流。下图说明了使用flatMap方法的效果。
在这里插入图片描述

总而言之,flatmap方法让你把一个流中的每个值都换成另一个流,然后把所有的流连接起来成为一个流。

举一反三

给定两个数字列表,如何返回所有的数对呢?例如,给定列表[1, 2, 3]和列表[3, 4],应该返回[(1, 3), (1, 4), (2, 3), (2, 4), (3, 3), (3, 4)]。为简单起见,你可以用有两个元素的数组来代表数对。

解答:
你可以使用两个map来迭代这两个列表,并生成数对。但这样会返回一个Stream-<Stream<Integer[]>>。你需要让生成的流扁平化,以得到一个Stream<Integer[]>。这
正是flatMap所做的:

List<Integer> numbers1 = Arrays.asList(1, 2, 3); 
List<Integer> numbers2 = Arrays.asList(3, 4); 
List<int[]> pairs = numbers1.stream() 
						.flatMap(i -> numbers2.stream() 
							.map(j -> new int[]{i, j}) 
						) 
 					.collect(toList());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杨幂等

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值