Java8核心特性實(shí)戰(zhàn)之五:Stream(流)—樂(lè)字節(jié)教育

[圖片上傳失敗...(image-f4ad7f-1597110338434)]

說(shuō)起流煤痕,我們會(huì)想起手機(jī) ,電腦組裝流水線接谨,物流倉(cāng)庫(kù)商品包裝流水線等等杭攻。如果把手機(jī) ,電腦,包裹看做最終結(jié)果的話,那么加工商品前的各種零部件就可以看做數(shù)據(jù)源,而中間一系列的加工作業(yè)操作疤坝,就可以看做流的處理兆解。

流的概念

Java Se中對(duì)于流的操作有輸入輸出IO流,而Java8中引入的Stream 屬于Java API中的一個(gè)新成員,它允許你以聲明性方式處理數(shù)據(jù)集合跑揉,Stream 使用一種類似 SQL 語(yǔ)句從數(shù)據(jù)庫(kù)查詢數(shù)據(jù)的直觀方式來(lái)提供一種對(duì) Java 集合運(yùn)算和表達(dá)的高階抽象锅睛。 注意這里的流操作可以看做是對(duì)集合數(shù)據(jù)的處理埠巨。

簡(jiǎn)單來(lái)說(shuō),流是一種數(shù)據(jù)渠道,用于操作數(shù)據(jù)源(集合、數(shù)組现拒、文件等)所生產(chǎn)的元素序列辣垒。

  • 源-流會(huì)使用一個(gè)提供數(shù)據(jù)的源,如集合、數(shù)組或輸入|輸出資源印蔬。

從有序集生成流時(shí)會(huì)保留原有的順序勋桶。由列表生成的流,其元素順序與列表一致

  • 元素序列-就像集合一樣侥猬,流也提供了一個(gè)接口,可以訪問(wèn)特定元素類型的一組有序值例驹。

  • 數(shù)據(jù)處理操作-流的數(shù)據(jù)處理功能支持類似于數(shù)據(jù)庫(kù)的操作(數(shù)據(jù)篩選、過(guò)濾退唠、排序等操作)鹃锈。

  • 流水線-多個(gè)流操作本身會(huì)返回一個(gè)流,多個(gè)操作就可以鏈接起來(lái),成為數(shù)據(jù)處理的一道流水線瞧预。

流&集合

  • 計(jì)算的時(shí)期

[圖片上傳失敗...(image-fc48a4-1597110338434)]

集合中數(shù)據(jù)都是計(jì)算完畢的數(shù)據(jù)屎债,例如從數(shù)據(jù)庫(kù)中查詢用戶記錄 按用戶id 查詢 降序排列 然后通過(guò)list 接收用戶記錄,數(shù)據(jù)的計(jì)算已在放入集合前完成垢油。 PS:獲取Java學(xué)習(xí)資料和輔導(dǎo)盆驹,lezijie007(暗號(hào)33)

流中數(shù)據(jù)按需計(jì)算,按照使用者的需要計(jì)算數(shù)據(jù)滩愁,例如通過(guò)搜索引擎進(jìn)行搜索躯喇,搜索出來(lái)的條目并不是全部呈現(xiàn)出來(lái)的,而且先顯示最符合的前 10 條或者前 20 條惊楼,只有在點(diǎn)擊 “下一頁(yè)” 的時(shí)候玖瘸,才會(huì)再輸出新的 10 條秸讹。流的計(jì)算也是這樣檀咙,當(dāng)用戶需要對(duì)應(yīng)數(shù)據(jù)時(shí),Stream 才會(huì)對(duì)其進(jìn)行計(jì)算處理璃诀。

  • 外部迭代與內(nèi)部迭代

[圖片上傳失敗...(image-c8c34e-1597110338434)]

把集合比作一個(gè)工廠的倉(cāng)庫(kù)的話弧可,一開始工廠硬件比較落后,要對(duì)貨物作什么修改劣欢,此時(shí)工人親自走進(jìn)倉(cāng)庫(kù)對(duì)貨物進(jìn)行處理棕诵,有時(shí)候還要將處理后的貨物轉(zhuǎn)運(yùn)到另一個(gè)倉(cāng)庫(kù)中。此時(shí)對(duì)于開發(fā)者來(lái)說(shuō)需要親自去做迭代凿将,一個(gè)個(gè)地找到需要的貨物校套,并進(jìn)行處理,這叫做外部迭代牧抵。

當(dāng)工廠發(fā)展起來(lái)后笛匙,配備了流水線作業(yè)侨把,工廠只要根據(jù)需求設(shè)計(jì)出相應(yīng)的流水線,然后工人只要把貨物放到流水線上妹孙,就可以等著接收成果了秋柄,而且流水線還可以根據(jù)要求直接把貨物輸送到相應(yīng)的倉(cāng)庫(kù)。

這就叫做內(nèi)部迭代蠢正,流水線已經(jīng)幫你把迭代給完成了骇笔,你只需要說(shuō)要干什么就可以了(即設(shè)計(jì)出合理的流水線)。相當(dāng)于 Java8 引入的Stream 對(duì)數(shù)據(jù)的處理實(shí)現(xiàn)了”自動(dòng)化”操作嚣崭。

流操作過(guò)程

[圖片上傳失敗...(image-63be79-1597110338434)]

整個(gè)流操作就是一條流水線笨触,將元素放在流水線上一個(gè)個(gè)地進(jìn)行處理。需要注意的是:很多流操作本身就會(huì)返回一個(gè)流有鹿,所以多個(gè)操作可以直接連接起來(lái)旭旭, 如下圖這樣,操作可以進(jìn)行鏈?zhǔn)秸{(diào)用葱跋,并且并行流還可以實(shí)現(xiàn)數(shù)據(jù)流并行處理操作持寄。

[圖片上傳失敗...(image-a6dbbb-1597110338434)]

總的來(lái)說(shuō),流操作過(guò)程分為三個(gè)階段:

  • 創(chuàng)建

借助數(shù)據(jù)源創(chuàng)建流對(duì)象

  • 中間處理

篩選娱俺、切片稍味、映射、排序等中間操作

  • 終止流

匹配荠卷、匯總模庐、分組等終止操作

流的創(chuàng)建

對(duì)流操作首先要?jiǎng)?chuàng)建對(duì)應(yīng)的流,流的創(chuàng)建集中形式如下:

[圖片上傳失敗...(image-15d817-1597110338434)]

1 集合創(chuàng)建流

在 Java 8 中, 集合接口有兩個(gè)方法來(lái)生成流:

  • stream() ? 為集合創(chuàng)建串行流油宜。

  • parallelStream() ? 為集合創(chuàng)建并行流掂碱。

示例代碼如下:

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n386" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public static void main(String[] args) {
/**

  • 定義集合l1 并為集合創(chuàng)建串行流
    */
    List<String> l1 = Arrays.asList("周星馳", "周杰倫", "周星星", "周潤(rùn)發(fā)");
    // 返回串行流
    l1.stream();
    // 返回并行流
    l1.parallelStream();
    }</pre>

上述操作得到的流是通過(guò)原始數(shù)據(jù)轉(zhuǎn)換過(guò)來(lái)的流,除了這種流創(chuàng)建的基本操作外慎冤,對(duì)于流的創(chuàng)建還有以下幾種方式疼燥。

2 值創(chuàng)建流

Stream.of(T...) : Stream.of("aa", "bb") 生成流

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n391" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">//值創(chuàng)建流 生成一個(gè)字符串流
Stream<String> stream = Stream.of("java8", "Spring", "SpringCloud");
stream.forEach(System.out::println);</pre>

3 數(shù)組創(chuàng)建流

根據(jù)參數(shù)的數(shù)組類型創(chuàng)建對(duì)應(yīng)的流。

  • Arrays.stream(T[ ])

  • Arrays.stream(int[ ])

  • Arrays.stream(double[ ])

  • Arrays.stream(long[ ])

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n404" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> /**

  • 這里以int 為例 long double 不再舉例
    */
    Stream stream = Arrays.stream(Arrays.asList(10, 20, 30, 40).toArray());
    // 根據(jù)數(shù)組索引范圍創(chuàng)建指定Stream
    stream = Arrays.stream(Arrays.asList(10, 20, 30, 40).toArray(), 0, 2);</pre>

4 文件生成流

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n407" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">stream = Files.lines(Paths.get("C:\java\jdbc.properties"));
System.out.println(stream.collect(Collectors.toList()));
// 指定字符集編碼
stream = Files.lines(Paths.get("C:\java\jdbc.properties"), Charset.forName("utf-8"));
System.out.println(stream.collect(Collectors.toList()));</pre>

5 函數(shù)生成流

兩個(gè)方法:

  • iterate : 依次對(duì)每個(gè)新生成的值應(yīng)用函數(shù)

  • generate :接受一個(gè)函數(shù)蚁堤,生成一個(gè)新的值

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n416" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // 重100 開始 生成偶數(shù)流
Stream.iterate(100, n -> n + 2);
// 產(chǎn)生1-100 隨機(jī)數(shù)
Stream.generate(() ->(int) (Math.random() * 100 + 1));</pre>

流中間操作

流的中間操作分為三大類:篩選切片醉者、映射、排序披诗。

篩選切片:類似sql 中where 條件判斷的意思撬即,對(duì)元素進(jìn)行篩選操作

映射:對(duì)元素結(jié)果進(jìn)行轉(zhuǎn)換 ,優(yōu)點(diǎn)類似select 字段意思或者對(duì)元素內(nèi)容進(jìn)行轉(zhuǎn)換處理

排序:比較好理解 呈队,常用sql 中按字段升序 降序操作

[圖片上傳失敗...(image-63cc90-1597110338433)]

流中間操作數(shù)據(jù)準(zhǔn)備(這里以訂單數(shù)據(jù)處理為例)

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n427" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">@Data
public class Order {
// 訂單id
private Integer id;
// 訂單用戶id
private Integer userId;
// 訂單編號(hào)
private String orderNo;
// 訂單日期
private Date orderDate;
// 收貨地址
private String address;
// 創(chuàng)建時(shí)間
private Date createDate;
// 更新時(shí)間
private Date updateDate;
// 訂單狀態(tài) 0-未支付 1-已支付 2-待發(fā)貨 3-已發(fā)貨 4-已接收 5-已完成
private Integer status;
// 是否有效 1-有效訂單 0-無(wú)效訂單
private Integer isValid;
//訂單總金額
private Double total;
}
?
Order order01 = new Order(1, 10, "20190301",
new Date(), "上海市-浦東區(qū)", new Date(), new Date(), 4, 1, 100.0);
Order order02 = new Order(2, 30, "20190302",
new Date(), "北京市四惠區(qū)", new Date(), new Date(), 1, 1, 2000.0);
Order order03 = new Order(3, 20, "20190303",
new Date(), "北京市-朝陽(yáng)區(qū)", new Date(), new Date(), 4, 1, 500.0);
Order order04 = new Order(4, 40, "20190304",
new Date(), "北京市-大興區(qū)", new Date(), new Date(), 4, 1, 256.0);
Order order05 = new Order(5, 40, "20190304",
new Date(), "上海市-松江區(qū)", new Date(), new Date(), 4, 1, 1000.0);
ordersList = Arrays.asList(order01, order02, order03, order04, order05);</pre>

篩選&切片

  • 篩選有效訂單

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n435" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">// 過(guò)濾有效訂單
ordersList.stream().filter((order) -> order.getIsValid() == 1)
.forEach(System.out::println);</pre>

  • 篩選有效訂單 取第一頁(yè)數(shù)據(jù)(每頁(yè)2條記錄)

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n439" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // 過(guò)濾有效訂單 取第一頁(yè)數(shù)據(jù)(每頁(yè)2條記錄)
ordersList.stream().filter((order) -> order.getIsValid() == 1)
.limit(2)
.forEach(System.out::println);</pre>

  • 篩選訂單集合有效訂單 取最后一條記錄

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n443" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">// 過(guò)濾訂單集合有效訂單 取最后一條記錄
ordersList.stream().filter((order) -> order.getIsValid() == 1)
.skip(ordersList.size() - 2) // 跳過(guò)前ordersList.size()-2 記錄
.forEach(System.out::println);</pre>

  • 篩選有效訂單 取第3頁(yè)數(shù)據(jù)(每頁(yè)2條記錄)

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n447" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">// 過(guò)濾有效訂單 取第3頁(yè)數(shù)據(jù)(每頁(yè)2條記錄) 并打印到控制臺(tái)
ordersList.stream().filter((order) -> order.getIsValid() == 1)
.skip((3 - 1) * 2)
.limit(2)
.forEach(System.out::println);</pre>

  • 篩選無(wú)效訂單去除重復(fù)訂單號(hào)記錄

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n451" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">// 過(guò)濾無(wú)效訂單 去除重復(fù)訂單號(hào)記錄 重寫Order equals 與 hashCode 方法
ordersList.stream().filter((order) -> order.getIsValid() == 0)
.distinct()
.forEach(System.out::println);</pre>

映射

  • 過(guò)濾有效訂單,獲取所有訂單編號(hào)

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n459" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">//過(guò)濾有效訂單剥槐,獲取所有訂單編號(hào)
ordersList.stream().filter((order) -> order.getIsValid() == 1)
.map((order) -> order.getOrderNo())
.forEach(System.out::println);</pre>

  • 過(guò)濾有效訂單 ,并分離每個(gè)訂單下收貨地址市區(qū)信息

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n463" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">ordersList.stream().map(o -> o.getAddress()
.split("-"))
.flatMap(Arrays::stream)
.forEach(System.out::println);</pre>

排序

  • 過(guò)濾有效訂單 根據(jù)用戶id 進(jìn)行排序

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n471" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">//過(guò)濾有效訂單 根據(jù)用戶id 進(jìn)行排序
ordersList.stream().filter((order) -> order.getIsValid() == 1)
.sorted((o1, o2) -> o1.getUserId() - o2.getUserId())
.forEach(System.out::println);

//或者等價(jià)寫法
ordersList.stream().filter((order) -> order.getIsValid() == 1)
.sorted(Comparator.comparingInt(Order::getUserId))
.forEach(System.out::println);</pre>

  • 過(guò)濾有效訂單 ,根據(jù)訂單狀態(tài)排序 如果訂單狀態(tài)相同根據(jù)訂單創(chuàng)建時(shí)間排序

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n475" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">//過(guò)濾有效訂單 如果訂單狀態(tài)相同 根據(jù)訂單創(chuàng)建時(shí)間排序 反之根據(jù)訂單狀態(tài)排序
ordersList.stream().filter((order) -> order.getIsValid() == 1)
.sorted((o1, o2) -> {
if (o1.getStatus().equals(o2.getStatus())) {
return o1.getCreateDate().compareTo(o2.getCreateDate());
} else {
return o1.getStatus().compareTo(o2.getStatus());
}})
.forEach(System.out::println);

// 等價(jià)形式
ordersList.stream().filter((order) -> order.getIsValid() == 1)
.sorted(Comparator.comparing(Order::getCreateDate)
.thenComparing(Comparator.comparing(Order::getStatus)))
.forEach(System.out::println);</pre>

流的終止操作

終止操作會(huì)從流的流水線生成結(jié)果。其結(jié)果是任何不是流的值宪摧,比如常見的List粒竖、 Integer迈喉,甚 至void等結(jié)果。對(duì)于流的終止操作温圆,分為以下三類:

[圖片上傳失敗...(image-81b0f3-1597110338433)]

查找與匹配

  • 篩選有效訂單 匹配是否全部為已支付訂單

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n489" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // 篩選有效訂單 匹配是否全部為已支付訂單
System.out.println("allMatch匹配結(jié)果:" +
ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.allMatch((o) -> o.getStatus() != 0)
);</pre>

  • 篩選有效訂單 匹配是否存在未支付訂單

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n494" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">// 篩選有效訂單 匹配是否存在未支付訂單
System.out.println("anyMatch匹配結(jié)果:" +
ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.anyMatch((o) -> o.getStatus() == 0)
);</pre>

  • 篩選有效訂單 全部未完成訂單

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n499" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">// 篩選有效訂單 全部未完成訂單
System.out.println("noneMatch匹配結(jié)果:" +
ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.noneMatch((o) -> o.getStatus() == 5)
);</pre>

  • 篩選有效訂單 返回第一條訂單

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n504" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // 篩選有效訂單 返回第一條訂單
System.out.println("findAny匹配結(jié)果:"+
ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.findAny()
.get()
);</pre>

  • 篩選所有有效訂單 返回訂單總數(shù)

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n509" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">// 篩選所有有效訂單 返回訂單總數(shù)
System.out.println("count結(jié)果:" +
ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.count()
);</pre>

  • 篩選有效訂單 返回金額最大訂單金額

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n514" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">// 篩選有效訂單 返回金額最大訂單金額
System.out.println("訂單金額最大值:" +
ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.map(Order::getTotal)
.max(Double::compare)
.get()
);</pre>

  • 篩選有效訂單 返回金額最小訂單金額

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n519" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">// 篩選有效訂單 返回金額最小訂單金額
System.out.println("訂單金額最小值:" +
ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.map(Order::getTotal)
.min(Double::compare)
.get()
);</pre>

歸約&收集

1 歸約

將流中元素反復(fù)結(jié)合起來(lái)挨摸,得到一個(gè)值的操作

  • 計(jì)算有效訂單總金額

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n529" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">// 計(jì)算有效訂單總金額
System.out.println("有效訂單總金額:" +
ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.map(Order::getTotal)
.reduce(Double::sum)
.get()
);</pre>

2 Collector數(shù)據(jù)收集

將流轉(zhuǎn)換為其他形式,coollect 方法作為終端操作岁歉, 接收一個(gè)Collector接口的實(shí)現(xiàn)得运,用于給Stream中元素做匯總的方法。最常用的方法锅移,把流中所有元素收集到一個(gè) List, Set 或 Collection中熔掺。

3 集合收集

常用集合收集方法 toList、toSet非剃、toCollection置逻、toMap等

  • 篩選所有有效訂單 并收集訂單列表

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n539" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">// 篩選所有有效訂單并收集訂單列表
ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.collect(Collectors.toList())
.forEach(System.out::println);</pre>

  • 篩選所有有效訂單并收集訂單號(hào)與訂單金額

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n543" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">// 篩選所有有效訂單 并收集訂單號(hào) 與 訂單金額
Map<String,Double> map=ordersList.stream().filter((order) -> order.getIsValid() == 1).
collect(Collectors.toMap(Order::getOrderNo, Order::getTotal));
// java8 下對(duì)map進(jìn)行遍歷操作 如果 Map的Key重復(fù),會(huì)報(bào)錯(cuò)
map.forEach((k,v)->{
System.out.println("k:"+k+":v:"+v);
});</pre>

匯總

匯總操作在Stream流操作比較常見,比如計(jì)算總數(shù)备绽,求平均等操作券坞,常用方法如下:

[圖片上傳失敗...(image-f8f46a-1597110338433)]

相關(guān)操作如下

  • 篩選所有有效訂單 返回訂單總數(shù)

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n554" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">System.out.println("count結(jié)果:"+
ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.collect(Collectors.counting())
);
System.out.println("count結(jié)果:"+
ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.count()
);</pre>

  • 返回訂單總金額

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n558" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">System.out.println("訂單總金額:"+
ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.collect(Collectors.summarizingDouble(Order::getTotal))
);
System.out.println("訂單總金額:"+
ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.mapToDouble(Order::getTotal)
.sum()
);
System.out.println("訂單總金額:"+
ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.map(Order::getTotal)
.reduce(Double::sum)
.get()
);</pre>

  • 返回用戶id=20 有效訂單平均每筆消費(fèi)金額

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n562" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">System.out.println("用戶id=20 有效訂單平均每筆消費(fèi)金額:"+
ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.filter((order -> order.getUserId()==20))
.collect(Collectors.averagingDouble(Order::getTotal))
);
System.out.println("用戶id=20 有效訂單平均每筆消費(fèi)金額:"+
ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.filter((order -> order.getUserId()==20))
.mapToDouble(Order::getTotal)
.average()
.getAsDouble()
);

System.out.println("用戶id=20 有效訂單平均每筆消費(fèi)金額:"+
ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.filter((order -> order.getUserId()==20))
.collect(Collectors.summarizingDouble(Order::getTotal))
.getAverage()
);</pre>

  • 篩選所有有效訂單 并計(jì)算訂單總金額

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n566" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">System.out.println("訂單總金額:"+
ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.collect(Collectors.summingDouble(Order::getTotal))
);</pre>

最值

  • 篩選所有有效訂單 并計(jì)算最小訂單金額

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n574" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">System.out.println("最小訂單金額:"+
ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.map(Order::getTotal)
.collect(Collectors.minBy(Double::compare))
);</pre>

  • 篩選所有有效訂單 并計(jì)算最大訂單金額

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n578" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">// 篩選所有有效訂單 并計(jì)算最大訂單金額
System.out.println("最大訂單金額:"+
ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.map(Order::getTotal)
.collect(Collectors.maxBy(Double::compare))
);</pre>

分組&分區(qū)

1 分組

groupingBy 用于將數(shù)據(jù)分組,最終返回一個(gè) Map 類型 肺素,groupingBy 第二參數(shù)用于實(shí)現(xiàn)多級(jí)分組

  • 根據(jù)有效訂單支付狀態(tài)進(jìn)行分組操作

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n589" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">Map<Integer,List<Order>> g01=ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.collect(Collectors.groupingBy(Order::getStatus));
g01.forEach((status,order)->{
System.out.println("----------------");
System.out.println("訂單狀態(tài):"+status);
order.forEach(System.out::println);
});</pre>

  • 篩選有效訂單恨锚,根據(jù)用戶id 和 支付狀態(tài)進(jìn)行分組

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n593" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">Map<Integer,Map<String,List<Order>>> g02= ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.collect(Collectors.groupingBy(Order::getUserId,
Collectors.groupingBy((o)->{
if(o.getStatus()==0){
return "未支付";
}else if (o.getStatus()==1){
return "已支付";
}else if (o.getStatus()==2){
return "待發(fā)貨";
}else if (o.getStatus()==3){
return "已發(fā)貨";
}else if (o.getStatus()==4){
return "已接收";
} else{
return "已完成";
}
}
))
);
g02.forEach((userId,m)->{
System.out.println("用戶id:"+userId+"-->有效訂單如下:");
m.forEach((status,os)->{
System.out.println("狀態(tài):"+status+"---訂單列表如下:");
os.forEach(System.out::println);
});
System.out.println("-----------------------");
});</pre>

2 分區(qū)

分區(qū)與分組的區(qū)別在于,分區(qū)是按照 true 和 false 來(lái)分的倍靡,因此partitioningBy 接受的參數(shù)的 lambda 也是 T -> boolean

  • 分區(qū)操作-篩選訂單金額>1000 的有效訂單

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n601" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">Map<Boolean,List<Order>> g03= ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.collect(Collectors.partitioningBy((o)->o.getTotal()>1000));
g03.forEach((b,os)->{
System.out.println("分區(qū)結(jié)果:"+b+"--列表結(jié)果:");
os.forEach(System.out::println);
});</pre>

  • 拼接操作-篩選有效訂單并進(jìn)行拼接

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n605" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">String orderStr=ordersList.stream()
.filter((order) -> order.getIsValid() == 1)
.map(Order::getOrderNo)
.collect(Collectors.joining(","));
System.out.println(orderStr);</pre>

流的應(yīng)用

Java8引入Stream流操作猴伶,使得對(duì)元素的處理更加的方便快捷,通過(guò)Stream提供的相關(guān)方法很好的結(jié)合Lambda塌西、函數(shù)式接口他挎、方法引用等相關(guān)內(nèi)容,使得流的處理相比較原始集合處理代碼極大簡(jiǎn)化捡需,Stream支持函數(shù)的鏈?zhǔn)秸{(diào)用办桨,代碼上更加緊湊同時(shí)Stream支持的元素的并行化處理提高了程序的執(zhí)行性能。

對(duì)于Stream流的應(yīng)用通常在集合元素?cái)?shù)據(jù)處理上特別是對(duì)元素需要進(jìn)行多次處理的情況栖忠,同時(shí)對(duì)于函數(shù)式編程的味道更加濃重崔挖,也是以后開發(fā)的一個(gè)趨勢(shì)贸街。

好了庵寞,Java8核心特性之Stream流就介紹到這里了,應(yīng)該是非常詳盡了薛匪,希望大家喜歡捐川。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市逸尖,隨后出現(xiàn)的幾起案子古沥,更是在濱河造成了極大的恐慌瘸右,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件岩齿,死亡現(xiàn)場(chǎng)離奇詭異太颤,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)盹沈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門龄章,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人乞封,你說(shuō)我怎么就攤上這事做裙。” “怎么了肃晚?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵锚贱,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我关串,道長(zhǎng)拧廊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任晋修,我火速辦了婚禮卦绣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘飞蚓。我一直安慰自己滤港,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布趴拧。 她就那樣靜靜地躺著溅漾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪著榴。 梳的紋絲不亂的頭發(fā)上添履,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音脑又,去河邊找鬼暮胧。 笑死,一個(gè)胖子當(dāng)著我的面吹牛问麸,可吹牛的內(nèi)容都是我干的往衷。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼严卖,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼席舍!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起哮笆,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤来颤,失蹤者是張志新(化名)和其女友劉穎汰扭,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體福铅,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡萝毛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了滑黔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片珊泳。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖拷沸,靈堂內(nèi)的尸體忽然破棺而出蔑赘,到底是詐尸還是另有隱情删壮,我是刑警寧澤耻姥,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布翩瓜,位于F島的核電站,受9級(jí)特大地震影響序无,放射性物質(zhì)發(fā)生泄漏验毡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一帝嗡、第九天 我趴在偏房一處隱蔽的房頂上張望晶通。 院中可真熱鬧,春花似錦哟玷、人聲如沸狮辽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)喉脖。三九已至,卻和暖如春抑月,著一層夾襖步出監(jiān)牢的瞬間树叽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工谦絮, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留题诵,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓层皱,卻偏偏與公主長(zhǎng)得像性锭,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子奶甘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354