map()和flatMap()
map()
只需将一个lambda参数作为Function即可,其中T是元素,R是使用T构建的返回元素。最后,我们将获得一个带有R类型对象的Stream。一个简单的示例可以是:
Stream
.of(1,2,3,4,5)
.map(myInt -> "preFix_"+myInt)
.forEach(System.out::println);
它仅Integer
使用Type的元素1到5 ,使用每个元素从String
具有值的type中构造一个新元素"prefix_"+integer_value
并将其打印出来。
flatMap()
知道flatMap()接受一个函数F<T, R>
,
T是一种类型,可以从中使用/来构建Stream。它可以是一个List(T.stream()),一个数组(Arrays.stream(someArray))等。任何Stream可以采用/或采用其形式的形式。在下面的示例中,每个开发人员都有多种语言,因此开发人员。语言是一个列表,将使用lambda参数。
R是将使用T生成的结果流。知道我们有T的许多实例,我们自然就会有R的许多流。类型R的所有这些流现在将合并为类型R的一个 “扁平”流。
例
Bachiri Taoufiq的示例在此处 看到其答案很简单且易于理解。为了清楚起见,只说我们有一个开发人员团队:
dev_team = {dev_1,dev_2,dev_3}
,每个开发人员都知道多种语言:
dev_1 = {lang_a,lang_b,lang_c},
dev_2 = {lang_d},
dev_2 = {lang_e,lang_f}
在dev_team上应用 Stream.map()以获得每个开发人员的语言:
dev_team.map(dev -> dev.getLanguages())
将为您提供以下结构:
{
{lang_a,lang_b,lang_c},
{lang_d},
{lang_e,lang_f}
}
这基本上是一个List<List<Languages>> /Object[Languages[]]
。不太漂亮,也不像Java8 !!
通过Stream.flatMap()
上面的结构,您可以将其“扁平化”
,并将其转换为{lang_a, lang_b, lang_c, lang_d, lang_e, lang_f}
,基本上可以用作List<Languages>/Language[]/etc
...
所以最后,您的代码将更像这样:
dev_team
.stream() /* {dev_1,dev_2,dev_3} */
.map(dev -> dev.getLanguages()) /* {{lang_a,...,lang_c},{lang_d}{lang_e,lang_f}}} */
.flatMap(languages -> languages.stream()) /* {lang_a,...,lang_d, lang_e, lang_f} */
.doWhateverWithYourNewStreamHere();
或者简单地:
dev_team
.stream() /* {dev_1,dev_2,dev_3} */
.flatMap(dev -> dev.getLanguages().stream()) /* {lang_a,...,lang_d, lang_e, lang_f} */
.doWhateverWithYourNewStreamHere();
何时使用map()和flatMap():
Java 8之前的版本:
List<Foo> myFoos = new ArrayList<Foo>();
for(Foo foo: myFoos){
for(Bar bar: foo.getMyBars()){
System.out.println(bar.getMyName());
}
}
Java 8后
myFoos
.stream()
.flatMap(foo -> foo.getMyBars().stream())
.forEach(bar -> System.out.println(bar.getMyName()));
map :: Stream T -> (T -> R) -> Stream R
,flatMap :: Stream T -> (T -> Stream R) -> Stream R
。