最近的需求里有這樣一個場景,要校驗一個集合中每個對象的多個Id的有效性。比如一個Customer對象,有3個Id:id1,id2,id3,要把這些Id全部取出來,然後去資料庫里查詢它是否存在。 @Data @AllArgsConstructor public class Customer { pri ...
最近的需求里有這樣一個場景,要校驗一個集合中每個對象的多個Id的有效性。比如一個Customer對象,有3個Id:id1
,id2
,id3
,要把這些Id全部取出來,然後去資料庫里查詢它是否存在。
@Data
@AllArgsConstructor
public class Customer {
private String name;
private String id1;
private String id2;
private String id3;
}
在通常情況下,我們要從集合中取出一個對象屬性,很好辦,用這個辦法:
customerList.stream().map(Customer::getId1).filter(Objects::nonNull).collect(Collectors.toList())
現在要取3個欄位,怎麼做呢?
Stream.concat
Stream介面中的靜態方法concat,可以把兩個流合成一個,我們取3個欄位可以合併兩次:
Stream<String> concat = Stream.concat(customerList.stream().map(Customer::getId1),
customerList.stream().map(Customer::getId2));
List<String> ids = Stream.concat(concat, customerList.stream().map(Customer::getId3))
.filter(Objects::nonNull)
.collect(Collectors.toList());
取4個欄位,就再繼續合併。但是這種不夠簡潔,可以使用扁平化流flatMap。
flatMap
flatmap方法讓你把一個流中的每個值都換成另一個流,然後把所有的流連接起來成為一個流。
Stream.flatMap
方法的入參為一個Function函數,函數返回值的泛型要求為Stream類型。對比一下,map
和flatMap
都是將流中的元素映射為我們想要的值,只是flatMap
映射的結果是一個新的Stream。
而Stream.of
方法剛好可以構建一個類型為Stream的原始流,以供flatMap
操作。
List<String> ids = Stream.of(customerList.stream().map(Customer::getId1),
customerList.stream().map(Customer::getId2),
customerList.stream().map(Customer::getId3))
.flatMap(idStream -> idStream)
.filter(Objects::nonNull)
.collect(Collectors.toList());
註意,Stream.of方法返回的流的泛型跟方法入參的類型是一樣,上面的代碼就相當於,Stream.of(stream, stream, stream)
, 得到的結果就是Stream<Stream>
,緊接著用flatMap
扁平化處理,把每一個元素合成一個新流。
本文來自博客園,作者:xfcoding,歡迎轉載:https://www.cnblogs.com/cloudrich/p/17375636.html