国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 開(kāi)發(fā) > Java > 正文

Java8處理集合的優(yōu)雅姿勢(shì)之Stream

2024-07-14 08:43:49
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

前言

在Java中,集合和數(shù)組是我們經(jīng)常會(huì)用到的數(shù)據(jù)結(jié)構(gòu),需要經(jīng)常對(duì)他們做增、刪、改、查、聚合、統(tǒng)計(jì)、過(guò)濾等操作。相比之下,關(guān)系型數(shù)據(jù)庫(kù)中也同樣有這些操作,但是在Java 8之前,集合和數(shù)組的處理并不是很便捷。

不過(guò),這一問(wèn)題在Java 8中得到了改善,Java 8 API添加了一個(gè)新的抽象稱為流Stream,可以讓你以一種聲明的方式處理數(shù)據(jù)。本文就來(lái)介紹下如何使用Stream。特別說(shuō)明一下,關(guān)于Stream的性能及原理不是本文的重點(diǎn),如果大家感興趣后面會(huì)出文章單獨(dú)介紹。

1.Stream介紹

Stream 使用一種類(lèi)似用 SQL 語(yǔ)句從數(shù)據(jù)庫(kù)查詢數(shù)據(jù)的直觀方式來(lái)提供一種對(duì) Java 集合運(yùn)算和表達(dá)的高階抽象。

Stream API可以極大提高Java程序員的生產(chǎn)力,讓程序員寫(xiě)出高效率、干凈、簡(jiǎn)潔的代碼。

這種風(fēng)格將要處理的元素集合看作一種流,流在管道中傳輸,并且可以在管道的節(jié)點(diǎn)上進(jìn)行處理,比如篩選,排序,聚合等。

Stream有以下特性及優(yōu)點(diǎn):

  • 無(wú)存儲(chǔ)。Stream不是一種數(shù)據(jù)結(jié)構(gòu),它只是某種數(shù)據(jù)源的一個(gè)視圖,數(shù)據(jù)源可以是一個(gè)數(shù)組,Java容器或I/O channel等。
  • 為函數(shù)式編程而生。對(duì)Stream的任何修改都不會(huì)修改背后的數(shù)據(jù)源,比如對(duì)Stream執(zhí)行過(guò)濾操作并不會(huì)刪除被過(guò)濾的元素,而是會(huì)產(chǎn)生一個(gè)不包含被過(guò)濾元素的新Stream。
  • 惰式執(zhí)行。Stream上的操作并不會(huì)立即執(zhí)行,只有等到用戶真正需要結(jié)果的時(shí)候才會(huì)執(zhí)行。
  • 可消費(fèi)性。Stream只能被“消費(fèi)”一次,一旦遍歷過(guò)就會(huì)失效,就像容器的迭代器那樣,想要再次遍歷必須重新生成。

我們舉一個(gè)例子,來(lái)看一下到底Stream可以做什么事情:

Java8,Stream

上面的例子中,獲取一些帶顏色塑料球作為數(shù)據(jù)源,首先過(guò)濾掉紅色的、把它們?nèi)诨呻S機(jī)的三角形。再過(guò)濾器并刪除小的三角形。最后計(jì)算出剩余圖形的周長(zhǎng)。

如上圖,對(duì)于流的處理,主要有三種關(guān)鍵性操作:分別是流的創(chuàng)建、中間操作(intermediate operation)以及最終操作(terminal operation)。

2.Stream的創(chuàng)建

在Java 8中,可以有多種方法來(lái)創(chuàng)建流。

1、通過(guò)已有的集合來(lái)創(chuàng)建流

在Java 8中,除了增加了很多Stream相關(guān)的類(lèi)以外,還對(duì)集合類(lèi)自身做了增強(qiáng),在其中增加了stream方法,可以將一個(gè)集合類(lèi)轉(zhuǎn)換成流。

List<String> strings = Arrays.asList("Hollis", "HollisChuang", "hollis", "Hello", "HelloWorld", "Hollis"); Stream<String> stream = strings.stream(); 

以上,通過(guò)一個(gè)已有的List創(chuàng)建一個(gè)流。除此以外,還有一個(gè)parallelStream方法,可以為集合創(chuàng)建一個(gè)并行流。

這種通過(guò)集合創(chuàng)建出一個(gè)Stream的方式也是比較常用的一種方式。

2、通過(guò)Stream創(chuàng)建流

可以使用Stream類(lèi)提供的方法,直接返回一個(gè)由指定元素組成的流。

Stream<String> stream = Stream.of("Hollis", "HollisChuang", "hollis", "Hello", "HelloWorld", "Hollis"); 

如以上代碼,直接通過(guò)of方法,創(chuàng)建并返回一個(gè)Stream。

3.Stream中間操作

Stream有很多中間操作,多個(gè)中間操作可以連接起來(lái)形成一個(gè)流水線,每一個(gè)中間操作就像流水線上的一個(gè)工人,每人工人都可以對(duì)流進(jìn)行加工,加工后得到的結(jié)果還是一個(gè)流。

Java8,Stream

以下是常用的中間操作列表:

Java8,Stream

filter

filter 方法用于通過(guò)設(shè)置的條件過(guò)濾出元素。以下代碼片段使用 filter 方法過(guò)濾掉空字符串:

List<String> strings = Arrays.asList("Hollis", "", "HollisChuang", "H", "hollis"); strings.stream().filter(string -> !string.isEmpty()).forEach(System.out::println); //Hollis, , HollisChuang, H, hollis 

map

map 方法用于映射每個(gè)元素到對(duì)應(yīng)的結(jié)果,以下代碼片段使用 map 輸出了元素對(duì)應(yīng)的平方數(shù):

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); numbers.stream().map( i -> i*i).forEach(System.out::println); //9,4,4,9,49,9,25 

limit/skip

limit 返回 Stream 的前面 n 個(gè)元素;skip 則是扔掉前 n 個(gè)元素。以下代碼片段使用 limit 方法保理4個(gè)元素:

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); numbers.stream().limit(4).forEach(System.out::println); //3,2,2,3 

sorted

sorted 方法用于對(duì)流進(jìn)行排序。以下代碼片段使用 sorted 方法進(jìn)行排序:

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); numbers.stream().sorted().forEach(System.out::println); //2,2,3,3,3,5,7 

distinct

distinct主要用來(lái)去重,以下代碼片段使用 distinct 對(duì)元素進(jìn)行去重:

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); numbers.stream().distinct().forEach(System.out::println); //3,2,7,5 

接下來(lái)我們通過(guò)一個(gè)例子和一張圖,來(lái)演示下,當(dāng)一個(gè)Stream先后通過(guò)filter、map、sort、limit以及distinct處理后會(huì)發(fā)生什么。

代碼如下:

List<String> strings = Arrays.asList("Hollis", "HollisChuang", "hollis", "Hello", "HelloWorld", "Hollis"); Stream s = strings.stream().filter(string -> string.length()<= 6).map(String::length).sorted().limit(3)    .distinct(); 

過(guò)程及每一步得到的結(jié)果如下圖:

Java8,Stream

4.Stream最終操作

Stream的中間操作得到的結(jié)果還是一個(gè)Stream,那么如何把一個(gè)Stream轉(zhuǎn)換成我們需要的類(lèi)型呢?比如計(jì)算出流中元素的個(gè)數(shù)、將流裝換成集合等。這就需要最終操作(terminal operation)

最終操作會(huì)消耗流,產(chǎn)生一個(gè)最終結(jié)果。也就是說(shuō),在最終操作之后,不能再次使用流,也不能在使用任何中間操作,否則將拋出異常:

java.lang.IllegalStateException: stream has already been operated upon or closed 

俗話說(shuō),“你永遠(yuǎn)不會(huì)兩次踏入同一條河”也正是這個(gè)意思。

常用的最終操作如下圖:

Java8,Stream

forEach

Stream 提供了方法 'forEach' 來(lái)迭代流中的每個(gè)數(shù)據(jù)。以下代碼片段使用 forEach 輸出了10個(gè)隨機(jī)數(shù):

Random random = new Random(); random.ints().limit(10).forEach(System.out::println); 

count

count用來(lái)統(tǒng)計(jì)流中的元素個(gè)數(shù)。

List<String> strings = Arrays.asList("Hollis", "HollisChuang", "hollis","Hollis666", "Hello", "HelloWorld", "Hollis"); System.out.println(strings.stream().count()); //7 

collect

collect就是一個(gè)歸約操作,可以接受各種做法作為參數(shù),將流中的元素累積成一個(gè)匯總結(jié)果:

List<String> strings = Arrays.asList("Hollis", "HollisChuang", "hollis","Hollis666", "Hello", "HelloWorld", "Hollis"); strings = strings.stream().filter(string -> string.startsWith("Hollis")).collect(Collectors.toList()); System.out.println(strings); //Hollis, HollisChuang, Hollis666, Hollis 

接下來(lái),我們還是使用一張圖,來(lái)演示下,前文的例子中,當(dāng)一個(gè)Stream先后通過(guò)filter、map、sort、limit以及distinct處理后會(huì),在分別使用不同的最終操作可以得到怎樣的結(jié)果。

下圖,展示了文中介紹的所有操作的位置、輸入、輸出以及使用一個(gè)案例展示了其結(jié)果。

Java8,Stream

5.總結(jié)

本文介紹了Java 8中的Stream 的用途,優(yōu)點(diǎn)等。還接受了Stream的幾種用法,分別是Stream創(chuàng)建、中間操作和最終操作。

Stream的創(chuàng)建有兩種方式,分別是通過(guò)集合類(lèi)的stream方法、通過(guò)Stream的of方法。

Stream的中間操作可以用來(lái)處理Stream,中間操作的輸入和輸出都是Stream,中間操作可以是過(guò)濾、轉(zhuǎn)換、排序等。

Stream的最終操作可以將Stream轉(zhuǎn)成其他形式,如計(jì)算出流中元素的個(gè)數(shù)、將流裝換成集合、以及元素的遍歷等。

好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)VeVb武林網(wǎng)的支持。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到JAVA教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 松江区| 襄城县| 上栗县| 焉耆| 石渠县| 建昌县| 永嘉县| 永吉县| 吉木乃县| 洛隆县| 新泰市| 浮山县| 潮州市| 江华| 榆树市| 科技| 定西市| 伽师县| 宁阳县| 德安县| 凤阳县| 丰县| 武乡县| 白银市| 香港| 湟源县| 福安市| 辽阳市| 顺平县| 河池市| 乌拉特前旗| 福建省| 同德县| 化隆| 清流县| 潜山县| 安阳市| 莱芜市| 平乡县| 荆门市| 凤台县|