1.函數(shù)定義比較
map注釋:
/**
* Returns a stream consisting of the results of applying the given
* function to the elements of this stream.
*
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
* @param <R> The element type of the new stream
* @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* function to apply to each element
* @return the new stream
*/
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
翻譯過來:
返回由將給定函數(shù)應(yīng)用于該流元素的結(jié)果組成的流。
這是一個(gè)中間操作。
參數(shù):
映射器-適用于每個(gè)元素的無干擾、無狀態(tài)功能
類型參數(shù):
新流的元素類型
返參:新流
也就是說你的集合中的元素是什么類型就返回該元素的流。
flatMap注釋:
/**
* Returns a stream consisting of the results of replacing each element of
* this stream with the contents of a mapped stream produced by applying
* the provided mapping function to each element. Each mapped stream is
* {@link java.util.stream.BaseStream#close() closed} after its contents
* have been placed into this stream. (If a mapped stream is {@code null}
* an empty stream is used, instead.)
*
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
* @apiNote
* The {@code flatMap()} operation has the effect of applying a one-to-many
* transformation to the elements of the stream, and then flattening the
* resulting elements into a new stream.
*
* <p><b>Examples.</b>
*
* <p>If {@code orders} is a stream of purchase orders, and each purchase
* order contains a collection of line items, then the following produces a
* stream containing all the line items in all the orders:
* <pre>{@code
* orders.flatMap(order -> order.getLineItems().stream())...
* }</pre>
*
* <p>If {@code path} is the path to a file, then the following produces a
* stream of the {@code words} contained in that file:
* <pre>{@code
* Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8);
* Stream<String> words = lines.flatMap(line -> Stream.of(line.split(" +")));
* }</pre>
* The {@code mapper} function passed to {@code flatMap} splits a line,
* using a simple regular expression, into an array of words, and then
* creates a stream of words from that array.
*
* @param <R> The element type of the new stream
* @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* function to apply to each element which produces a stream
* of new values
* @return the new stream
*/
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
翻譯過來:
返回由將該流的每個(gè)元素替換為通過將所提供的映射功能應(yīng)用到每個(gè)元素而產(chǎn)生的映射流的內(nèi)容的結(jié)果組成的流肛走。每個(gè)映射的流在其內(nèi)容已被放置到該流中之后被關(guān)閉假抄。(如果映射的流是空的拌牲,則使用空的流责循。)
這是一個(gè)中間操作贵试。
參數(shù):
映射器-無干擾琉兜、無狀態(tài)功能,適用于產(chǎn)生新數(shù)值流的每個(gè)元素
類型參數(shù):
新流的元素類型
返參:
新流
Apinote:
FlatMap()操作具有對(duì)該流的元素應(yīng)用一對(duì)多變換的效果毙玻,然后將所得到的元素展平到新的流中豌蟋。
案例.
如果訂單是采購(gòu)訂單的流,并且每個(gè)采購(gòu)訂單包含一系列行項(xiàng)目桑滩,則以下將生成包含所有訂單中所有行項(xiàng)目的流:
orders.flatMap(order -> order.getLineItems().stream())...
如果路徑是到文件的路徑梧疲,則以下會(huì)產(chǎn)生包含在該文件中的單詞的流:
Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8);
Stream<String> words = lines.flatMap(line -> Stream.of(line.split(" +")));
傳遞到FlatMap的映射器函數(shù)使用簡(jiǎn)單正則表達(dá)式將一行分割為單詞數(shù)組,然后從該數(shù)組創(chuàng)建一個(gè)單詞流
我的理解是假如你的集合流中包含子集合,那么使用flatMap
可以返回該子集合的集合流.
2.案例比較
假如我們有地址類
运准,一個(gè)地址類
包含多個(gè)城市
將地址類作為集合幌氮,我們想輸出所有的城市的名字。
數(shù)據(jù)結(jié)構(gòu):
1.jpg
地址類
:
//地址類
public class Address {
private String province;
private List<String> cityList;//市集合
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public List<String> getCityList() {
return cityList;
}
public void setCityList(List<String> cityList) {
this.cityList = cityList;
}
@Override
public String toString() {
return "Address{" +
"province='" + province + '\'' +
", cityList=" + cityList +
'}';
}
}
測(cè)試案例
public static void main(String[] args) {
List<String> cityListOne = new ArrayList<>();
cityListOne.add("鄭州");
cityListOne.add("濮陽(yáng)");
List<String> cityListTwo = new ArrayList<>();
cityListTwo.add("廊坊");
cityListTwo.add("邢臺(tái)");
List<String> cityListThree = new ArrayList<>();
cityListThree.add("大同");
cityListThree.add("太原");
List<String> cityListFour = new ArrayList<>();
cityListFour.add("南昌");
cityListFour.add("九江");
Address addressOne = new Address();
addressOne.setProvince("河南");
addressOne.setCityList(cityListOne);
Address addressTwo = new Address();
addressTwo.setProvince("河北");
addressTwo.setCityList(cityListTwo);
Address addressThree = new Address();
addressThree.setProvince("山西");
addressThree.setCityList(cityListThree);
Address addressFour = new Address();
addressFour.setProvince("江西");
addressFour.setCityList(cityListFour);
List<Address> addresseList = new ArrayList<>();
addresseList.add(addressOne);
addresseList.add(addressTwo);
addresseList.add(addressThree);
addresseList.add(addressFour);
//使用map輸出所有的城市名稱
addresseList.stream()
.map(a -> a.getCityList())
.forEach(cityList->{ cityList.forEach(city -> System.out.print(city));
});
System.out.println("");
//使用flatMap輸出所有城市名稱
addresseList.stream()
.flatMap(a -> a.getCityList().stream())
.forEach(city -> System.out.print(city));
}
輸出結(jié)果
鄭州濮陽(yáng)廊坊邢臺(tái)大同太原南昌九江
鄭州濮陽(yáng)廊坊邢臺(tái)大同太原南昌九江
可以看出兩個(gè)循環(huán)結(jié)果一致胁澳,但是map
處理方式是在foreach
中將cityList
作為集合再次循環(huán)该互,而flatMap
可以直接將cityList
中的城市直接進(jìn)行循環(huán)輸出。也就是說flatMap
可以獲取集合中的集合的流在外層可以直接處理
3.map強(qiáng)行獲取流會(huì)如何韭畸?
如果我們使用map
強(qiáng)行獲取流進(jìn)行循環(huán)會(huì)如何呢慢洋?
//使用map輸出所有的城市名稱
addresseList.stream()
.map(a -> a.getCityList())
.forEach(cityList->{ cityList.forEach(city -> System.out.print(city));
});
//使用map強(qiáng)行獲取流進(jìn)行輸出塘雳,寫法和flatMap一致
addresseList.stream()
.map(a -> a.getCityList().stream())
.forEach(city->System.out.println(city));
//使用flatMap輸出所有城市名稱
addresseList.stream()
.flatMap(a -> a.getCityList().stream())
.forEach(city -> System.out.print(city));
打印結(jié)果:
鄭州濮陽(yáng)廊坊邢臺(tái)大同太原南昌九江
java.util.stream.ReferencePipeline$Head@21588809
java.util.stream.ReferencePipeline$Head@2aae9190
java.util.stream.ReferencePipeline$Head@2f333739
java.util.stream.ReferencePipeline$Head@77468bd9
鄭州濮陽(yáng)廊坊邢臺(tái)大同太原南昌九江
可以看到使用map
如果和flatMap
寫法一樣強(qiáng)行獲取流進(jìn)行打印,打印的是流對(duì)象的信息普筹,而不是流對(duì)象中的集合信息败明。
4.使用多次flatMap
flatMap
也可以使用多次,則會(huì)把更深一層的集合流中的數(shù)據(jù)在外層進(jìn)行處理
在上面的案例中太防,我們假如再添加一個(gè)用戶類
用戶類
中包含地址類集合
數(shù)據(jù)結(jié)構(gòu)
2.jpg
用戶類
public class User {
private String name;
private List<Address> addressList;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Address> getAddressList() {
return addressList;
}
public void setAddressList(List<Address> addressList) {
this.addressList = addressList;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", addressList=" + addressList +
'}';
}
}
測(cè)試案例
public static void main(String[] args) {
List<String> cityListOne = new ArrayList<>();
cityListOne.add("鄭州");
cityListOne.add("濮陽(yáng)");
List<String> cityListTwo = new ArrayList<>();
cityListTwo.add("廊坊");
cityListTwo.add("邢臺(tái)");
List<String> cityListThree = new ArrayList<>();
cityListThree.add("大同");
cityListThree.add("太原");
List<String> cityListFour = new ArrayList<>();
cityListFour.add("南昌");
cityListFour.add("九江");
Address addressOne = new Address();
addressOne.setProvince("河南");
addressOne.setCityList(cityListOne);
Address addressTwo = new Address();
addressTwo.setProvince("河北");
addressTwo.setCityList(cityListTwo);
Address addressThree = new Address();
addressThree.setProvince("山西");
addressThree.setCityList(cityListThree);
Address addressFour = new Address();
addressFour.setProvince("江西");
addressFour.setCityList(cityListFour);
List<Address> addresseListOne = new ArrayList<>();
addresseListOne.add(addressOne);
addresseListOne.add(addressTwo);
List<Address> addresseListTwo = new ArrayList<>();
addresseListTwo.add(addressThree);
addresseListTwo.add(addressFour);
//新增用戶來包含地址集合
List<User> userList = new ArrayList<>();
User u1 = new User();
u1.setName("張三");
u1.setAddressList(addresseListOne);
User u2 = new User();
u2.setName("李四");
u2.setAddressList(addresseListTwo);
userList.add(u1);
userList.add(u2);
//使用map輸出所有的城市名稱
userList.stream()
.map(u->u.getAddressList())
.forEach(addressList->{
addressList.forEach(address -> {
address.getCityList().forEach(city->{
System.out.print(city);
});
});
});
System.out.println("");//換行
//使用flatMap輸出所有城市名稱
userList.stream()
.flatMap(u -> u.getAddressList().stream())
.flatMap(a -> a.getCityList().stream())
.forEach(city -> System.out.print(city));
}
打印結(jié)果
鄭州濮陽(yáng)廊坊邢臺(tái)大同太原南昌九江
鄭州濮陽(yáng)廊坊邢臺(tái)大同太原南昌九江
可以看出flatMap
可以使用多次將更深一層的集合流中的數(shù)據(jù)拿到外層進(jìn)行處理妻顶。而使用map
則相當(dāng)繁瑣
以上就是我對(duì)java8中map
和flatMap
的理解