欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java?Stream流語(yǔ)法示例詳解

 更新時(shí)間:2022年04月07日 10:08:57   作者:liangshitian  
這篇文章主要為大家詳細(xì)介紹了Java的Stream流,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助

如何使用Stream?

聚合操作是Java 8針對(duì)集合類(lèi),使編程更為便利的方式,可以與Lambda表達(dá)式一起使用,達(dá)到更加簡(jiǎn)潔的目的。

前面例子中,對(duì)聚合操作的使用可以歸結(jié)為3個(gè)部分:

1)  創(chuàng)建Stream:通過(guò)stream()方法,取得集合對(duì)象的數(shù)據(jù)集。   

2)  Intermediate:通過(guò)一系列中間(Intermediate)方法,對(duì)數(shù)據(jù)集進(jìn)行過(guò)濾、檢索等數(shù)據(jù)集的再次處理。如上例中,使用filter()方法來(lái)         對(duì)數(shù)據(jù)集進(jìn)行過(guò)濾。      

3)  Terminal通過(guò)最終(terminal)方法完成對(duì)數(shù)據(jù)集中元素的處理。如上例中,使用forEach()完成對(duì)過(guò)濾后元素的打印。     

在一次聚合操作中,可以有多個(gè)Intermediate,但是有且只有一個(gè)Terminal。也就是說(shuō),在對(duì)一個(gè)Stream可以進(jìn)行多次轉(zhuǎn)換操作,并不是每次都對(duì)Stream的每個(gè)元素執(zhí)行轉(zhuǎn)換。并不像for循環(huán)中,循環(huán)N次,其時(shí)間復(fù)雜度就是N。轉(zhuǎn)換操作是lazy(惰性求值)的,只有在Terminal操作執(zhí)行時(shí),才會(huì)一次性執(zhí)行??梢赃@么認(rèn)為,Stream 里有個(gè)操作函數(shù)的集合,每次轉(zhuǎn)換操作就是把轉(zhuǎn)換函數(shù)放入這個(gè)集合中,在 Terminal 操作的時(shí)候循環(huán) Stream 對(duì)應(yīng)的集合,然后對(duì)每個(gè)元素執(zhí)行所有的函數(shù)。

Stream的操作分類(lèi)

剛才提到的Stream的操作有Intermediate、Terminal和Short-circuiting:

Intermediate:map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 skip、 parallel、 sequential、 unordered

Terminal:forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、iterator

Short-circuiting: anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limit

1、創(chuàng)建流

如果是數(shù)組的話(huà),可以使用 Arrays.stream() 或者 Stream.of() 創(chuàng)建流;如果是集合的話(huà),可以直接使用 stream() 方法創(chuàng)建流,因?yàn)樵摲椒ㄒ呀?jīng)添加到 Collection 接口中。

public class CreateStreamDemo {
    public static void main(String[] args) {
        String[] arr = new String[]{"武漢加油", "中國(guó)加油", "世界加油"};
        Stream<String> stream = Arrays.stream(arr);
        stream = Stream.of("武漢加油", "中國(guó)加油", "世界加油");
        List<String> list = new ArrayList<>();
        list.add("武漢加油");
        list.add("中國(guó)加油");
        list.add("世界加油");
        stream = list.stream();
    }
}

查看 Stream 源碼的話(huà),你會(huì)發(fā)現(xiàn) of() 方法內(nèi)部其實(shí)調(diào)用了 Arrays.stream() 方法。

public static<T> Stream<T> of(T... values) {
    return Arrays.stream(values);
}

另外,集合還可以調(diào)用 parallelStream() 方法創(chuàng)建并發(fā)流,默認(rèn)使用的是 ForkJoinPool.commonPool()線(xiàn)程池。

List<Long> aList = new ArrayList<>();
Stream<Long> parallelStream = aList.parallelStream();

2、操作流

Stream 類(lèi)提供了很多有用的操作流的方法,我來(lái)挑一些常用的給你介紹一下。

1)過(guò)濾

通過(guò) filter() 方法可以從流中篩選出我們想要的元素。

public class FilterStreamDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("周杰倫");
        list.add("王力宏");
        list.add("陶喆");
        list.add("林俊杰");
        Stream<String> stream = list.stream().filter(element -> element.contains("王"));
        stream.forEach(System.out::println);
    }
}

filter() 方法接收的是一個(gè) Predicate(Java 8 新增的一個(gè)函數(shù)式接口,接受一個(gè)輸入?yún)?shù)返回一個(gè)布爾值結(jié)果)類(lèi)型的參數(shù),因此,我們可以直接將一個(gè) Lambda 表達(dá)式傳遞給該方法,比如說(shuō) element -> element.contains("王") 就是篩選出帶有“王”的字符串。

forEach() 方法接收的是一個(gè) Consumer(Java 8 新增的一個(gè)函數(shù)式接口,接受一個(gè)輸入?yún)?shù)并且無(wú)返回的操作)類(lèi)型的參數(shù),類(lèi)名 :: 方法名是 Java 8 引入的新語(yǔ)法,System.out 返回 PrintStream 類(lèi),println 方法你應(yīng)該知道是打印的。

stream.forEach(System.out::println); 相當(dāng)于在 for 循環(huán)中打印,類(lèi)似于下面的代碼:

for (String s : strs) {
    System.out.println(s);
}

很明顯,一行代碼看起來(lái)更簡(jiǎn)潔一些。來(lái)看一下程序的輸出結(jié)果:

王力宏

2)映射

如果想通過(guò)某種操作把一個(gè)流中的元素轉(zhuǎn)化成新的流中的元素,可以使用 map() 方法。

public class MapStreamDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("周杰倫");
        list.add("王力宏");
        list.add("陶喆");
        list.add("林俊杰");
        Stream<Integer> stream = list.stream().map(String::length);
        stream.forEach(System.out::println);
    }
}

map() 方法接收的是一個(gè) Function(Java 8 新增的一個(gè)函數(shù)式接口,接受一個(gè)輸入?yún)?shù) T,返回一個(gè)結(jié)果 R)類(lèi)型的參數(shù),此時(shí)參數(shù) 為 String 類(lèi)的 length 方法,也就是把 Stream<String> 的流轉(zhuǎn)成一個(gè) Stream<Integer> 的流。

程序輸出的結(jié)果如下所示:

3
3
2
3

3)匹配

Stream 類(lèi)提供了三個(gè)方法可供進(jìn)行元素匹配,它們分別是:

anyMatch(),只要有一個(gè)元素匹配傳入的條件,就返回 true。

allMatch(),只有有一個(gè)元素不匹配傳入的條件,就返回 false;如果全部匹配,則返回 true。

noneMatch(),只要有一個(gè)元素匹配傳入的條件,就返回 false;如果全部匹配,則返回 true。

public class MatchStreamDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("周杰倫");
        list.add("王力宏");
        list.add("陶喆");
        list.add("林俊杰");
        boolean  anyMatchFlag = list.stream().anyMatch(element -> element.contains("王"));
        boolean  allMatchFlag = list.stream().allMatch(element -> element.length() > 1);
        boolean  noneMatchFlag = list.stream().noneMatch(element -> element.endsWith("沉"));
        System.out.println(anyMatchFlag);
        System.out.println(allMatchFlag);
        System.out.println(noneMatchFlag);
    }
}

因?yàn)?ldquo;王力宏”以“王”字開(kāi)頭,所以 anyMatchFlag 應(yīng)該為 true;因?yàn)?ldquo;周杰倫”、“王力宏”、“陶喆”、“林俊杰”的字符串長(zhǎng)度都大于 1,所以 allMatchFlag 為 true;因?yàn)?4 個(gè)字符串結(jié)尾都不是“沉”,所以 noneMatchFlag 為 true。

程序輸出的結(jié)果如下所示:

true
true
true

4)組合

reduce() 方法的主要作用是把 Stream 中的元素組合起來(lái),它有兩種用法:

Optional<T> reduce(BinaryOperator<T> accumulator)

沒(méi)有起始值,只有一個(gè)參數(shù),就是運(yùn)算規(guī)則,此時(shí)返回 Optional。

T reduce(T identity, BinaryOperator<T> accumulator)

有起始值,有運(yùn)算規(guī)則,兩個(gè)參數(shù),此時(shí)返回的類(lèi)型和起始值類(lèi)型一致。

來(lái)看下面這個(gè)例子。

public class ReduceStreamDemo {
    public static void main(String[] args) {
        Integer[] ints = {0, 1, 2, 3};
        List<Integer> list = Arrays.asList(ints);
        Optional<Integer> optional = list.stream().reduce((a, b) -> a + b);
        Optional<Integer> optional1 = list.stream().reduce(Integer::sum);
        System.out.println(optional.orElse(0));
        System.out.println(optional1.orElse(0));
        int reduce = list.stream().reduce(6, (a, b) -> a + b);
        System.out.println(reduce);
        int reduce1 = list.stream().reduce(6, Integer::sum);
        System.out.println(reduce1);
    }
}

運(yùn)算規(guī)則可以是 Lambda 表達(dá)式(比如 (a, b) -> a + b),也可以是類(lèi)名::方法名(比如 Integer::sum)。

程序運(yùn)行的結(jié)果如下所示:

6
6
12
12

0、1、2、3 在沒(méi)有起始值相加的時(shí)候結(jié)果為 6;有起始值 6 的時(shí)候結(jié)果為 12。

3、轉(zhuǎn)換流

既然可以把集合或者數(shù)組轉(zhuǎn)成流,那么也應(yīng)該有對(duì)應(yīng)的方法,將流轉(zhuǎn)換回去——collect() 方法就滿(mǎn)足了這種需求。

public class CollectStreamDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("周杰倫");
        list.add("王力宏");
        list.add("陶喆");
        list.add("林俊杰");
        String[] strArray = list.stream().toArray(String[]::new);
        System.out.println(Arrays.toString(strArray));
        List<Integer> list1 = list.stream().map(String::length).collect(Collectors.toList());
        List<String> list2 = list.stream().collect(Collectors.toCollection(ArrayList::new));
        System.out.println(list1);
        System.out.println(list2);
        String str = list.stream().collect(Collectors.joining(", ")).toString();
        System.out.println(str);
    }
}

toArray() 方法可以將流轉(zhuǎn)換成數(shù)組,你可能比較好奇的是 String[]::new,它是什么東東呢?來(lái)看一下 toArray() 方法的源碼。

<A> A[] toArray(IntFunction<A[]> generator);

也就是說(shuō) String[]::new 是一個(gè) IntFunction,一個(gè)可以產(chǎn)生所需的新數(shù)組的函數(shù),可以通過(guò)反編譯字節(jié)碼看看它到底是什么:

String[] strArray = (String[])list.stream().toArray((x$0) -> {
    return new String[x$0];
});
System.out.println(Arrays.toString(strArray));

也就是相當(dāng)于返回了一個(gè)指定長(zhǎng)度的字符串?dāng)?shù)組。

當(dāng)我們需要把一個(gè)集合按照某種規(guī)則轉(zhuǎn)成另外一個(gè)集合的時(shí)候,就可以配套使用 map() 方法和 collect() 方法。

List<Integer> list1 = list.stream().map(String::length).collect(Collectors.toList());

通過(guò) stream() 方法創(chuàng)建集合的流后,再通過(guò) map(String:length) 將其映射為字符串長(zhǎng)度的一個(gè)新流,最后通過(guò) collect() 方法將其轉(zhuǎn)換成新的集合。

Collectors 是一個(gè)收集器的工具類(lèi),內(nèi)置了一系列收集器實(shí)現(xiàn),比如說(shuō) toList() 方法將元素收集到一個(gè)新的 java.util.List 中;比如說(shuō) toCollection() 方法將元素收集到一個(gè)新的 java.util.ArrayList 中;比如說(shuō) joining() 方法將元素收集到一個(gè)可以用分隔符指定的字符串中。

來(lái)看一下程序的輸出結(jié)果:

[周杰倫, 王力宏, 陶喆, 林俊杰]
[3, 3, 2, 3]
[周杰倫, 王力宏, 陶喆, 林俊杰]
周杰倫, 王力宏, 陶喆, 林俊杰

以上就是Java Stream流語(yǔ)法示例詳解的詳細(xì)內(nèi)容,更多關(guān)于JavaStream流的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 深入了解Java并發(fā)AQS的獨(dú)占鎖模式

    深入了解Java并發(fā)AQS的獨(dú)占鎖模式

    AQS是一種提供了原子式管理同步狀態(tài)、阻塞和喚醒線(xiàn)程功能以及隊(duì)列模型的簡(jiǎn)單框架。一般來(lái)說(shuō),同步工具實(shí)現(xiàn)鎖的控制分為獨(dú)占鎖和共享鎖,而AQS提供了對(duì)這兩種模式的支持。本文主要來(lái)介紹一下獨(dú)占鎖模式,需要的可以參考一下
    2022-10-10
  • lambda表達(dá)式解決java后臺(tái)分組排序過(guò)程解析

    lambda表達(dá)式解決java后臺(tái)分組排序過(guò)程解析

    這篇文章主要介紹了lambda表達(dá)式解決java后臺(tái)分組排序過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • 十大常見(jiàn)Java String問(wèn)題_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    十大常見(jiàn)Java String問(wèn)題_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    本文介紹Java中關(guān)于String最常見(jiàn)的10個(gè)問(wèn)題,需要的朋友參考下吧
    2017-04-04
  • Java遍歷Map對(duì)象集合的六種方式代碼示例

    Java遍歷Map對(duì)象集合的六種方式代碼示例

    Java中的Map是一種鍵值對(duì)映射的數(shù)據(jù)結(jié)構(gòu),它提供了一些常用的方法用于獲取、添加、刪除和修改元素,下面這篇文章主要給大家介紹了關(guān)于Java遍歷Map對(duì)象集合的六種方式,需要的朋友可以參考下
    2024-02-02
  • Java面向?qū)ο笾畠?nèi)部類(lèi)案例講解

    Java面向?qū)ο笾畠?nèi)部類(lèi)案例講解

    這篇文章主要介紹了Java面向?qū)ο笾畠?nèi)部類(lèi)案例講解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • JavaI/O深入學(xué)習(xí)之輸入和輸出

    JavaI/O深入學(xué)習(xí)之輸入和輸出

    這篇文章主要介紹了JavaI/O深入學(xué)習(xí)之輸入和輸出,Java類(lèi)庫(kù)中的I/O類(lèi)分成輸入和輸出兩部分,可以在JDK文檔里的類(lèi)層次結(jié)構(gòu)中查看到。,需要的朋友可以參考下
    2019-06-06
  • 兩分鐘解決IntelliJ IDEA中文亂碼問(wèn)題(推薦)

    兩分鐘解決IntelliJ IDEA中文亂碼問(wèn)題(推薦)

    這篇文章主要介紹了兩分鐘解決IntelliJ IDEA中文亂碼問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • SpringMVC深入講解文件的上傳下載實(shí)現(xiàn)

    SpringMVC深入講解文件的上傳下載實(shí)現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了springMVC實(shí)現(xiàn)文件上傳和下載的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • JSON.toJSONString()空字段不忽略修改的問(wèn)題

    JSON.toJSONString()空字段不忽略修改的問(wèn)題

    這篇文章主要介紹了JSON.toJSONString()空字段不忽略修改的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Java 中的 print() 和 println()

    Java 中的 print() 和 println()

    這篇文章主要介紹了Java 中的 print() 和 println(),Java 中的 print()和println()方法用于在控制臺(tái)上顯示文本,下面來(lái)看看它們之間到底有什么區(qū)別吧,需要的朋友也可以參考一下
    2021-11-11

最新評(píng)論