Java流(Stream)操作例項-篩選、對映、查詢匹配
準備工作
構建一個測試類,通過測試類先初始化一個數據源,具體如下。
public class TestObject {
private String name;
private String sex;
private int age;
private String email;
private boolean isMng;
public TestObject() {
}
public TestObject(String name,String sex,int age,String email,boolean isMng){
this .name=name;
this.sex=sex;
this.age=age;
this.email=email;
this.isMng=isMng;
}
//... ...get、set方法就不貼出來了,多又麻煩
}
在測試類中定義初始化資料來源
public class StreamOperation {
static List<TestObject> list = Arrays.asList(
new TestObject("Ron","M",10,"[email protected] ",false),
new TestObject("KDS","W",10,"[email protected]",false),
new TestObject("BoDuo","W",30,"[email protected]",false),
new TestObject("CangJin","W",10,"[email protected]",false),
new TestObject("XiaoZe","W",30,"[email protected]",true),
new TestObject("James","M",10,"[email protected]",true),
new TestObject("Allen","M",50,"[email protected]",true),
new TestObject("Smith","M",10,"[email protected]",true),
new TestObject("Wade","M",20,"[email protected]",true),
new TestObject("Wade","M",20,"[email protected]",false)
);
//... ...流操作
}
用謂詞篩選
Streams介面支援filter方法,該操作會接受一個謂詞(一個返回boolean的函式)作為引數,並返回一個包括所有符合謂詞的元素的流。比如我們需要篩選isLeader為ture的資料並列印名字就可以按照如下的方式處理。
/**
* @Comment 獲取Leader
* @Author Ron
* @Date 2017年11月24日 下午2:01:16
* @return
*/
public static List<TestObject> getLeader() {
return list.stream().filter(TestObject::isLeader).collect(Collectors.toList());
}
public static void main(String[] args) {
List<TestObject> leaders = getLeader();
leaders.stream().forEach(leader->System.out.println(leader.getName()));
}
篩選各異的元素
流還支援一個叫作distinct的方法,它會返回一個元素各異(根據流所生成元素的hashCode和equals方法實現)的流。例如,以下程式碼會篩選出列表中所有的偶數,並確保沒有重複。
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);
numbers.stream().filter(i -> i % 2 == 0).distinct().forEach(System.out::println);
}
截短流
流支援limit(n)方法,該方法會返回一個不超過給定長度的流。所需的長度作為引數傳遞給limit。如果流是有序的,則最多會返回前n個元素。比如選出前5個sex為M的物件並列印其名稱可以按如下的程式碼操作。
list.stream().filter(u->u.getSex().equals("M")).limit(5).forEach(u->System.out.println(u.getName()));
如果我們需要選出前5個sex為M的物件並按照名稱排序之後列印其名稱可以按如下的程式碼操作。
list.stream()
.filter(u->u.getSex().equals("M"))
.limit(5)
.sorted(Comparator.comparing(TestObject::getName))
.forEach(u->System.out.println(u.getName()));
跳過元素
流還支援skip(n)方法,返回一個扔掉了前n個元素的流。如果流中元素不足n個,則返回一個空流。請注意, limit(n)和skip(n)是互補的。例如,下面的程式碼將會跳過篩選出來的第一個元素並列印名字。
list.stream()
.filter(u->u.getSex().equals("M"))
.sorted(Comparator.comparing(TestObject::getName))
.skip(1)
.forEach(u->System.out.println(u.getName()));
對流中每一個元素應用函式
流支援map方法,它會接受一個函式作為引數。這個函式會被應用到每個元素上,並將其對映成一個新的元素(使用對映一詞,是因為它和轉換類似,但其中的細微差別在於它是“建立一個新版本”而不是去“修改”)。例如,下面的程式碼把方法引用TestObject::getName傳給了map方法,來提取流中使用者的名稱並列印:
list.stream()
.map(TestObject::getName)
.collect(Collectors.toList())
.forEach(System.out::println);
因為getName方法返回一個String,所以map方法輸出的流的型別就是StreamString>。
我們來再看一個例子,我們把方法引用TestObject::getName傳給了map方法,來提取流中使用者的名稱,然後再列印使用者名稱稱的長度。你可以像下面這樣,給map傳遞一個方法引用String::length來解決這個問題:
list.stream()
.map(TestObject::getName)
.map(String::length)
.collect(Collectors.toList())
.forEach(System.out::println);
檢查謂詞是否至少匹配一個元素
anyMatch方法可以回答“流中是否有一個元素能匹配給定的謂詞”。比如,你可以用它來看看使用者列表裡面是否有名稱為Ron的物件可選擇:
if(list.stream().anyMatch(u->u.getName().equals("Ron"))){
System.out.println("Ron已經到了");
}
anyMatch方法返回一個boolean,因此是一個終端操作。
檢查謂詞是否匹配所有元素
allMatch方法的工作原理和anyMatch類似,但它會看看流中的元素是否都能匹配給定的謂詞。比如,你可以用它來看看使用者是否都大於10歲。
if(list.stream().allMatch(u->u.getAge()>=10)){
System.out.println("很棒,都大於10歲");
}else{
System.out.println("原來都還沒發育");
}
和allMatch相對的是noneMatch。它可以確保流中沒有任何元素與給定的謂詞匹配。比如,你可以用noneMatch重寫前面的例子:
if(list.stream().noneMatch(u->u.getAge()<10)){
System.out.println("很棒,都大於10歲");
}else{
System.out.println("原來都還沒發育");
}
anyMatch、 allMatch和noneMatch這三個操作都用到了我們所謂的短路,這就是大家熟悉的Java中&&和||運算子短路在流中的版本。
Optional簡介
Optional<T>類(java.util.Optional)是一個容器類,代表一個值存在或不存在。Java 8的庫設計人員引入了Optional<T>,這樣就不用返回眾所周知容易出問題的null了。Optional裡面幾種可以迫使你顯式地檢查值是否存在或處理值不存在的情形。
- isPresent()將在Optional包含值的時候返回true, 否則返回false。
- ifPresent(Consumer block)會在值存在的時候執行給定的程式碼塊。
- T get()會在值存在時返回值,否則丟擲一個NoSuchElement異常。
- T orElse(T other)會在值存在時返回值,否則返回一個預設值。
查詢元素
findAny方法將返回當前流中的任意元素。它可以與其他流操作結合使用。
例如,我們需要顯示的檢查是否存在一個名為‘Ron’的人並顯示其名稱就可以按照如下的程式碼操作。
list.stream()
.filter(u->u.getName().equals("Ron"))
.findAny()
.ifPresent(u->System.out.println(u.getName()));
流水線將在後臺進行優化使其只需走一遍,並在利用短路找到結果時立即結束。
查詢第一個元素
有些流有一個出現順序(encounter order)來指定流中專案出現的邏輯順序(比如由List或排序好的資料列生成的流)。對於這種流,你可能想要找到第一個元素。為此有一個findFirst方法,它的工作方式類似於findany。
例如我們需要找到第一個isLeader為ture的物件並列印其名字,就可以按照如下的程式碼操作。
list.stream()
.filter(u->u.isLeader())
.findFirst()
.ifPresent(u->System.out.println(u.getName()));
何時使用findFirst和findAny
你可能會想,為什麼會同時有findFirst和findAny呢?答案是並行。找到第一個元素在並行上限制更多。如果你不關心返回的元素是哪個,請使用findAny,因為它在使用並行流時限制較少。
參考:Java8實戰
相關推薦
Java流(Stream)操作例項-篩選、對映、查詢匹配
準備工作 構建一個測試類,通過測試類先初始化一個數據源,具體如下。 public class TestObject { private String name; private String sex; private int ag
Java流(Stream)簡介
流簡介 要討論流,我們先來談談集合,這是最容易上手的方式了。 Java 8中的集合支援一個新的stream方法,它會返回一個流(介面定義在java.util.stream.Stream裡)。那麼, 流到底是什麼呢?簡短的定義就是“從支援資料處理操作的源生成的元
Java-函數語言程式設計(三)流(Stream)
流使程式猿可以在抽象層上對集合進行操作。 從外部迭代到內部迭代 什麼是外部迭代和內部迭代呢? 個人認為,外和內是相對集合程式碼而言。 如果迭代的業務執行在應用程式碼中,稱之為外部迭代。 反之,迭代的業務執行在集合程式碼中,稱為內部迭代(函數語言程式設計)。 語言描述可能有點抽象,下面看例項。
nodeJs文件系統(fs)與流(stream)
writer pipe 常用事件 urn 種類型 發生 成功 fin console 一、簡介 本文將介紹node.js文件系統(fs)和流(stream)的一些API已經參數使用情況。 二、目錄 文件系統將介紹以下方法: 1.fs.readFile
封裝位元組流(byte[])操作類 c#
在網路通訊中,資料在網路傳輸的格式必須以位元組流的形式進行,因此需要我們對位元組流進行寫入和讀出的操作,下面將會封裝兩個類,用來將各種型別的資料寫入位元組流,和從位元組流中讀取各種型別的資料。如下讀取類:NetBufferReaderusing System; using S
nodeJs檔案系統(fs)與流(stream)
檔案系統(File System): 在Node中,檔案系統的互動是非常重要的,伺服器的本質就是將本地的檔案傳送給客戶端, Node通過fs模組來和檔案系統進行互動,該模組提供了一些標準的檔案訪問API類開啟、讀取、寫入檔案、以及與其互動。 要是用fs模組,首先要從核心模組中載入; 使用 co
nodejs筆記之流(stream)
nis tab and 出錯 htm ons 設置 索引 進行 nodejs的stream有四種流類型: 可讀:Readable可寫:Writable可讀可寫:Duplex操作被寫入數據,然後讀出結果:Transform常用事件:data:有數據可讀時觸發end:沒有數據可
初學 Java web(二)application例項
利用application實現簡單的聊天室 login.jsp完成功能: 接收使用者名稱,提交給chat.jsp chat.jsp完成功能 獲取登入使用者名稱,顯示歡迎資訊 從application物件中獲取所有使用者的聊天記錄,並顯示(使用application物件的g
Java註解(Annotation)——3 例項
本例子旨在使用自定義註解為實體打上標記,為自動生成 sql 提供依據,模擬 hibernate 的註解,至於註解的原理自己搜吧1.定義 Table 註解package test; import java.lang.annotation.Documented; import
跟我學 Java 8 新特性之 Stream 流(三)縮減操作
和前面兩篇文章一起服用,效果會更佳。通過對流API的基礎體驗Demo和關鍵知識點的講解,相信大家對流API都有一定的認識了,但是流API強大的功能,可不僅僅像前面兩篇文章中說的那樣簡單,大家應該注意到,在第二篇中,我對Stream介面進行介紹的時候,並沒有把他的全部方法都
跟我學 Java 8 新特性之 Stream 流(四)並行流
隨著對流API認識的慢慢深入,本章我們要討論的知識點是流API裡面的並行流了。 在開始討論並行流之前,我先引發一下大家的思考,就你看到這篇文章的時間,你們是不是經常聽到,Intel i7 CPU什麼8核16執行緒,什麼Android手機8核4GB這種訊息,既然我們是處於
跟我學 Java 8 新特性之 Stream 流(二)關鍵知識點
我們的第一篇文章,主要是通過一個Demo,讓大家體驗了一下使用流API的那種酣暢淋漓的感覺。如果你沒有實踐,我還是再次呼籲你動手敲一敲,自己實實在跑一遍上一篇的Demo。 相信你的感受和理解也會隨之加深的。繼續探索流API的高階功能之前,我們先從介面級別全面瞭解一下流A
跟我學 Java 8 新特性之 Stream 流(六)收集
我們前面的五篇文章基本都是在說將一個集合轉成一個流,然後對流進行操作,其實這種操作是最多的,但有時候我們也是需要從流中收集起一些元素,並以集合的方式返回,我們把這種反向操作稱為收集。 流API也給我們提供了相應的方法。 如何在流中使用收集功能? 我們先看一看流API
跟我學 Java 8 新特性之 Stream 流(七)流與迭代器,流系列大結局
恭喜你們,馬上就要學完Java8 Stream流的一整系列了,其實我相信Stream流對很多使用Java的同學來說,都是一個知識盲點,因為這個原因,我才這麼細緻地講解Stream流的各個知識點,通過這一整個系列,我相信只要認真看了的同學,都已掌握的差不多了,就差實戰了。
黑馬程式設計師——Java IO流(二)之流操作規律總結、File類、Properties類、序列流等
-----------android培訓、java培訓、java學習型技術部落格、期待與您交流!------------ 六、流操作規律總結 1.明確源和目的: 源: 字元流:FileReader(純文字檔案)。 位元組流:FileInputStream(
java基礎之I/O流(一)------------字元流的檔案讀寫操作
一.流的概念: java的輸入輸出稱為流,流是一組有順序的集合。而流的本質則是資料傳輸 二.流的分類: 1.根據處理的功能分為位元組流(InputStream,OutPutStrean)和字元流(Writer,Reader)
【Selenium2+Java自動化(3)】-操作瀏覽的基本方法
臨時文件 mage 關閉 log 開始 str 打開 img bsp 前言 前面已經把環境搭建好了,這從這篇開始,正式學習selenium的webdriver框架。我們平常說的 selenium自動化,其實它並不是類似於QTP之類的有GUI界面的可視化工具,我們要學的是
Java IO 字節流與字符流 (二)
減少 rgs 作文 設計 fileinput src != tro 關閉 概述 IO流用來處理設備之間的數據傳輸 Java對數據的操作時通過流的方式 Java用於操作流的對象都在IO包中 流按操作的數據分為:字節流和字符流 流按流向不同分為:輸入流和輸出流 IO流常用基類
Java IO 字節流與字符流 (三)
length 相關操作 數組 new throws mce 存在 () put Java的IO流分為字符流(Reader,Writer)和字節流(InputStream,OutputStream),字節流顧名思義字節流就是將文件的內容讀取到字節數組,然後再輸出到另一個文件
java 核心編程——IO流之字符流(三)
sun logs printf file start ech read private per 1.字符流 1.1 所有文件的存儲都是字節的存儲,我們日常在磁盤上保存的其實並不是文件的字符,而是先把字符轉換成字節,再把這些字節儲存到磁盤。在讀取文件時,也是一個字節一個字