最近的需求里有這樣一個(gè)場景,要校驗(yàn)一個(gè)集合中每個(gè)對象的多個(gè)Id的有效性。比如一個(gè)Customer對象,有3個(gè)Id:id1
,id2
,id3
,要把這些Id全部取出來,然后去數(shù)據(jù)庫里查詢它們是否存在。
@Data
public class Customer {
private String name;
private String id1;
private String id2;
private String id3;
}
通常情況下,我們都是從集合中取出對象的某一個(gè)字段,像這樣:
List<String> id1s =
customerList.stream().map(Customer::getId1).filter(Objects::nonNull).collect(Collectors.toList());
現(xiàn)在要取3個(gè)字段,怎么做呢?
Stream.concat
Stream接口中的靜態(tài)方法concat,可以把兩個(gè)流合成一個(gè),我們?nèi)?個(gè)字段可以合并兩次:
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個(gè)字段,就再繼續(xù)合并。但是這種不夠簡潔,可以使用扁平化流flatMap
。
flatMap
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
flatMap
方法讓你把一個(gè)流中的每個(gè)值都換成另一個(gè)流,然后把所有的流連接起來成為一個(gè)流。
Stream.flatMap
方法的入?yún)橐粋€(gè)Function
函數(shù),函數(shù)返回值的泛型要求為Stream類型。對比來看,map
和flatMap
都是將流中的元素映射為我們想要的值,只是flatMap
把流中元素映射為一個(gè)新的Stream。
Stream.of(T... values)
方法將多個(gè)元素構(gòu)建成一個(gè)流,相當(dāng)于Arrays.stream
方法,元素本身為Stream時(shí)就可以構(gòu)建一個(gè)泛型為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());
上面的代碼就相當(dāng)于,Stream.of(stream, stream, stream)
, 得到的結(jié)果就是Stream<Stream>
,而flatMap
要將元素映射為Stream,所以flatMap
中的Lambda表達(dá)式返回本身即可,然后把多個(gè)流合成一個(gè)新流。
加深印象
再舉一個(gè)例子,假設(shè)有這樣一個(gè)需求:有一個(gè)由逗號連接的字符串組成的數(shù)組,如{"1,2,3", "3,4,5"}
,要求合并為一個(gè)數(shù)組,并去重,如{"1", "2", "3", "4", "5"}
。文章來源:http://www.zghlxwxcb.cn/news/detail-434478.html
public static void main(String[] args) {
String[] strArray = {"1,2,3", "3,4,5"};
List<String> collect = Arrays.stream(strArray) // Stream<String>
.map(str -> str.split(",")) // Stream<String[]>
.flatMap(Arrays::stream) // Stream<String>
.distinct()
.collect(Collectors.toList());
System.out.println(collect);
}
map
函數(shù)將元素映射為一個(gè)數(shù)組,flatMap
函數(shù)再將元素映射為一個(gè)Stream,并將所有Stream合并成一個(gè)新Stream,然后就能愉快操作流中的每個(gè)元素了。文章來源地址http://www.zghlxwxcb.cn/news/detail-434478.html
到了這里,關(guān)于Java8 Stream流的合并的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!