java flatmap_Java 8 Steam API map和flatMap方法使用详解
java 8 stream api 中有兩個(gè)方法map和flatMap非常實(shí)用,應(yīng)用場景也非常廣泛,能極大提升編程效率。下面我們詳細(xì)介紹一下這兩個(gè)方法的用法。
map方法
我們來看個(gè)示例:把一個(gè)整數(shù)列表轉(zhuǎn)換成字符串列表,java 8之前常用的實(shí)現(xiàn)方法如下
List numList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
List strList = new ArrayList<>();
for (int num : numList) {
strList.add(Integer.toString(num));
}
這種寫法比較符合直覺,但略顯繁瑣。如果用java 8的stream api的map方法則可以把這個(gè)過程變的非常簡潔
List strList = numList.stream()
.map(it -> Integer.toString(it))
.collect(Collectors.toList());
map方法接受一個(gè)lambda表達(dá)式,這個(gè)表達(dá)式是一個(gè)函數(shù),輸入類型是集合元素的類型,輸出類型是任意類型
it -> Integer.toString(it)
在示例中就是將集合中的整數(shù)元素逐個(gè)轉(zhuǎn)換成字符串類型。這種寫法和常規(guī)的編程思路不同,卻有點(diǎn)像SQL
select id from table1
這條SQL語句讀取一張表的id字段,id是int類型,我們將他轉(zhuǎn)換成字符類型,實(shí)現(xiàn)方法如下
select cast(id as CHAR(10)) as id from table1
SQL中的select對應(yīng)的是map方法
cast(id as CHAR(10)) 對應(yīng)的就是 it -> Integer.toString(it)
我們還可以用map實(shí)現(xiàn)很多效果,比如轉(zhuǎn)換成符合要求的bool列表
List boolList = numList.stream()
.map(it -> it > 5 ? true : false)
.collect(Collectors.toList());
或者轉(zhuǎn)換成某種對象列表
public class Main {
private static class Klass {
private int field;
public Klass(int field) {
this.field = field;
}
@Override
public String toString() {
return "field=" + field;
}
}
public static void main(String[] args) {
List numList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
List objList = numList.stream()
.map(it -> new Klass(it))
.collect(Collectors.toList());
}
}
都可以非常迅速的實(shí)現(xiàn),和那些流水賬式的代碼告別
List objList2 = new ArrayList<>();
for (int num : numList) {
objList2.add(new Klass(num));
}
其實(shí)這種寫法就是函數(shù)式編程的聲明性編程,將代碼寫成表達(dá)式類型。而我們常用的SQL語言天生就是函數(shù)式語言。
flatMap方法
我們把需求擴(kuò)展下
先定義兩個(gè)類型
private static class Klass {
private int field;
public Klass(int field) {
this.field = field;
}
@Override
public String toString() {
return "field=" + field;
}
}
private static class KlassGroup {
private List group = new ArrayList<>();
public KlassGroup(Klass... objList) {
for (Klass item : objList) {
this.group.add(item);
}
}
public List getKlassList() {
return group;
}
}
KlassGroup類中定義了一個(gè)Klass類的列表
現(xiàn)在我們有一組KlassGroup對象
List groupList = Arrays.asList(
new KlassGroup(new Klass(1), new Klass(2), new Klass(3)),
new KlassGroup(new Klass(4), new Klass(5), new Klass(6)),
new KlassGroup(new Klass(7), new Klass(8), new Klass(9)),
new KlassGroup(new Klass(10))
);
需要將每個(gè)KlassGroup對象中的那些Klass類取出來,放到一個(gè)ArrayList里面,得到一個(gè)List。我們嘗試著用map方法來實(shí)現(xiàn)
List> result = groupList.stream()
.map(it -> it.getKlassList())
.collect(Collectors.toList());
哈,不成功,我們想要的結(jié)果是List,現(xiàn)在得到了 List>。當(dāng)然,我們可以輕而易舉的解決這個(gè)問題
List result2 = new ArrayList<>();
for (KlassGroup group : groupList) {
for (Klass klass : group.getKlassList()) {
result2.add(klass);
}
}
但是這種套了兩層for循環(huán)的代碼太丑陋了。面對這種需求,flatMap可以大展身手了
List result3 = groupList.stream()
.flatMap(it -> it.getKlassList().stream())
.collect(Collectors.toList());
一行代碼就實(shí)現(xiàn)了
stream api 的 flatMap方法接受一個(gè)lambda表達(dá)式函數(shù), 函數(shù)的返回值必須也是一個(gè)stream類型,flatMap方法最終會(huì)把所有返回的stream合并,map方法做不到這一點(diǎn),如果用map去實(shí)現(xiàn),會(huì)變成這樣一個(gè)東西
List> result3 = groupList.stream()
.map(it -> it.getKlassList().stream())
.collect(Collectors.toList());
flatMap的思路在其他語言中也有體現(xiàn),比如C# Linq中的 SelectMany 方法,F# 中的 List.collect方法都有同樣的作用。用函數(shù)式編程的說法,他們都實(shí)現(xiàn)了 monad,當(dāng)然,monad這個(gè)概念很難是通俗的描述清楚,此文中就不展開了。
java 8 stream api 中各方法可以極大的簡化集合操作,帶來大幅度的編碼效率提升,如果是java 8及以上的版本,一定要優(yōu)先使用,stream api絕對是java中史詩級的工作效率提升利器。
總結(jié)
以上是生活随笔為你收集整理的java flatmap_Java 8 Steam API map和flatMap方法使用详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql aes encrypt_my
- 下一篇: java自定义 filter,HBase