Java0steam_Java學習 - Stream 使用

Java Stream使用

這段時間在學數據庫和Java,發現Java的Stream實際上和數據庫的查詢操作非常類似。這里簡單介紹Stream的用法,并和Sql Server中的操作聯系起來。

此文為初學Stream所寫,以后對Stream有更深的理解后會重寫

當我們使用一個流的時候,通常包括三個基本步驟:

獲取一個數據源(source)

數據轉換

執行操作獲取想要的結果

每次轉換原有 Stream 對象不改變,返回一個新的 Stream 對象(可以有多次轉換),這就允許對其操作可以像鏈條一樣排列,變成一個管道,如下圖所示。

ba832f29af9355c4fe65ee610a31501e.png

一、創建 stream

有多種方式生成 Stream Source:

從 Collection 和數組

Collection.stream()

Collection.parallelStream()

Arrays.stream(T array) or Stream.of()

從 BufferedReader

java.io.BufferedReader.lines()

靜態工廠

java.util.stream.IntStream.range()

java.nio.file.Files.walk()

自己構建

java.util.Spliterator

其它

Random.ints()

BitSet.stream()

Pattern.splitAsStream(java.lang.CharSequence)

JarFile.stream()

創建Stream示例

// 1. Individual values

Stream stream = Stream.of("a", "b", "c");

// 2. Arrays

String [] strArray = new String[] {"a", "b", "c"};

stream = Stream.of(strArray);

stream = Arrays.stream(strArray);

// 3. Collections

List list = Arrays.asList(strArray);

stream = list.stream();

二、stream 操作

stream的操作分為兩大類,一類為中間操作,一類為終端操作。

中間操作:返回值仍然為一個流,不會消耗流

終端操作:返回最終結果;終端操作會消耗掉流,使之不再可用

1.stream.filter()

stream.filter() 是一個中間操作

baf7e4cce39d5f9d6022f5e31442b653.png

stream.filter()用于對stream進行某種篩選,stream.filter() 相當于Sql server 中,from ... where ...

在filter()中應當給出篩選條件,準確的說,應該實現Predicate接口,這個接口將被應用于stream中的每一個元素,判斷其是否應該被包含在結果stream中。

這個接口只有一個抽象方法待用戶實現

4f0a8ac23103257d244c91df437ce687.png

抽象方法應該返回一個布爾值,當布爾值為真時,stream.filter()將這個元素包含在結果stream中

stream.filter()使用示例:創建Integer流,然后篩選出偶數

ArrayList arrlist = new ArrayList();

Stream st = arrlist.stream();

Stream st2 = st.filter(new Predicate() {

@Override

public boolean test(Integer arg0) {

return arg0 % 2 == 0;

}

});

還可以用lambda表達式來實現

ArrayList arrlist = new ArrayList();

Stream st = arrlist.stream();

Stream st2 = st.filter((o1)->(o1 % 2 == 0));

關于Predicate接口,它還有.and(),.or(),.negate(),.isEqual()四個默認方法,這里不多介紹。但這些方法也十分常用,對于稍微復雜一點的邏輯就需要使用。

使用Precicate接口需要導入

import java.util.function.Predicate;

9f53b92f3ac6a26864a514ec474d499a.png

2.stream.map()

stream.map()是一個中間操作

7429ab47e7a0fbf260ab148a64bb7dcd.png

stream.map()用于對stream進行某種映射,stream.map() 相當于Sql server 中,select

雖然這么說不太恰當,因為Sql sever 的select實際上時 SQL語言中 \(\sigma , \prod\)的加和,而stream.map() 應該是\(\prod\).

在stream.map()中應該指定轉換條件,準確的說,應該實現一個Function()接口,這個接口將被用于stream的每一個元素,將元素按照一定的映射關系映射成新的元素。

Function接口的參數意義

2466ec6f40dd2b7c394f1603bcef48a8.png

使用Function接口需要導入

import java.util.function.Function;

這個接口只有一個抽象方法待用戶實現

e31839b5728a09aa179b931fbb065331.png

抽象方法apply() 接受一個T類型的參數,返回一個R類型的結果

stream.map()使用示例:創建Integer流,然后映射到其原值的兩倍

ArrayList arrlist = new ArrayList();

for(int i = 1; i <= 5; i++) {

arrlist.add(i);

}

Stream st = arrlist.stream();

Stream st2 = st.map(new Function() {

@Override

public Integer apply(Integer arg0) {

return arg0 * 2;

}

});

ArrayList ans = new ArrayList();

ans = (ArrayList) st2.collect(Collectors.toList());

for(Integer i : ans) {

System.out.print(i + " ");

}

還可以用lambda表達式來實現

// 初學可以先不這么寫

ArrayList ans = (ArrayList)arrlist.stream()

.map((o1)->(2*o1))

.collect(Collectors.toList());

stream.map() 的幾種其他形式

IntStream mapToInt(ToIntFunction super T> mapper);

LongStream mapToLong(ToLongFunction super T> mapper);

DoubleStream mapToDouble(ToDoubleFunction super T> mapper);

這三者實際上是對\(Function\) 中 R的固定封裝

3.stream.flatMap()

stream.flatMap()是一個中間操作

4d35cda63c5f0ee2fb3ddb444671fd12.png

stream.flatMap()和stream.map()都是進行映射的方法,區別在于,flatMap()處理的元素類型仍是流,flagMap用于將若干個流先拆分成若干個單個元素,再整合成一個流,即流的合并。

簡單來說,flatMap()將集合的集合降維成單個元素的集合

實例: 將數組\([[1,2,3],[4,5,6],[7,8],[9]]\)轉化為[1,2,3,4,5,6,7,8,9]

ArrayList> list_2 = new ArrayList<>();

list_2.add(new ArrayList<>(Arrays.asList(1,2,3)));

list_2.add(new ArrayList<>(Arrays.asList(4,5,6)));

list_2.add(new ArrayList<>(Arrays.asList(7,8)));

list_2.add(new ArrayList<>(Arrays.asList(9)));

ArrayList list_1 = (ArrayList) list_2.stream()

// list_2.stream() 為 "[1,2,3]" "[4,5,6]" "[7,8]" "[9]" 每個""表示流的不同元素

.flatMap((o1)->(o1).stream())

// 以 o1 = "[1,2,3]"為例,(o1)->(o1).stream() 轉化為"1","2","3"

.collect(Collectors.toList());

for(Integer i : list_1) {

System.out.print(i+" ");

}

stream.flagMap()的幾種其他形式

IntStream flatMapToInt(Function super T, ? extends IntStream> mapper);

LongStream flatMapToLong(Function super T, ? extends LongStream> mapper);

DoubleStream flatMapToDouble(Function super T, ? extends DoubleStream> mapper);

這三者實際上是對\(Function\) 中 R的固定封裝

4.stream.allMatch() ,stream.anyMatch() 和 stream.noneMatch()

stream.allMatch() 和 stream.anyMatch()均為終端操作

da97a0775382658d926b94f8b8827803.png

傳入一個Predicate函數式接口,用于指定條件

5.stream.collect()

stream.collect()為終端操作

7818c790464944b2824d01474021083c.png

Stream的核心在于collect,即對數據的收集。

用法一:將流轉化為Collection或Map

Collectors.toCollection() 將數據轉換成Collection,只要是Collection的實現都可以,例如ArrayList,HashSet,該方法能夠接受一個Collection對象

示例:

//List

Stream.of(1,2,3,4,5,6,7,8,9).collect(Collectors.toCollection(ArrayList::new));

//Set

Stream.of(1,2,3,4,5,6,7,8,9).collect(Collectors.toCollection(HashSet::new));

// Stream.of(1,2,3,4,5,6,7,8,9).collect(Collectors.toList());

// Stream.of(1,2,3,4,5,6,7,8,9).collect(Collectors.toSet());

// Stream.of(1,2,3,4,5,6,7,8,9).collect(Collectors.toMap(key,value));

用法二:字符串聚合規約

Collectors.joining(),拼接,有三個重載方法,底層實現是StringBuilder,通過append方法拼接到一起,并且可以自定義分隔符(這個感覺還是很有用的,很多時候需要把一個list轉成一個String,指定分隔符就可以實現了,非常方便)、前綴、后綴。

Student studentA = new Student("20190001", "小明");

Student studentB = new Student("20190002", "小紅");

Student studentC = new Student("20190003", "小丁");

//使用分隔符:201900012019000220190003

Stream.of(studentA, studentB, studentC)

.map(Student::getId)

.collect(Collectors.joining());

//使用^_^ 作為分隔符

//20190001^_^20190002^_^20190003

Stream.of(studentA, studentB, studentC)

.map(Student::getId)

.collect(Collectors.joining("^_^"));

//使用^_^ 作為分隔符

//[]作為前后綴

//[20190001^_^20190002^_^20190003]

Stream.of(studentA, studentB, studentC)

.map(Student::getId)

.collect(Collectors.joining("^_^", "[", "]"));

用法三:統計個數

Collectors.counting() 統計元素個數,這個和Stream.count() 作用都是一樣的,返回的類型一個是包裝Long,另一個是基本long,但是他們的使用場景還是有區別的,這個后面再提。

// Long 8

Stream.of(1,0,-10,9,8,100,200,-80)

.collect(Collectors.counting());

//如果僅僅只是為了統計,那就沒必要使用Collectors了,那樣更消耗資源

// long 8

Stream.of(1,0,-10,9,8,100,200,-80)

.count();

用法四:集合分組

Collectos.groupingBy()實現集合分組,返回值為一個Map

假如現在有一個實體Student

public class Student {

private String name;

private int score;

private int age;

public Student(String name,int score,int age){

this.name = name;

this.score = score;

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getScore() {

return score;

}

public void setScore(int score) {

this.score = score;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

}

現在對其按照Name分組

Map> StrListStrMap = students.stream()

.collect(Collectors.groupingBy(Student::getName));

6.stream.forEach() 和

stream.forEach() 終端操作

stream.forEach()遍歷流中的每一個元素,不一定依靠流的順序,而stream.forEachOrdered()按照流的順序遍歷。

Stream.of(1,2,3,4,5,6).forEach(System.out::println);

7.stream.max() , stream.min() , stream.count()

三個終端操作

stream.max()返回流中的最大值

stream.min()返回流中的最小值

未傳入Comparator則填null,默認用Comparable的compareTo函數比較。

stream.count()返回流中元素個數

8.stream.findAny()

返回流中任意一個元素,如果流為空,返回一個空的Optional.

List list = Arrays.asList(1, 2, 3, 4, 5, 6);

Optional any = list.stream().findAny();

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/443214.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/443214.shtml
英文地址,請注明出處:http://en.pswp.cn/news/443214.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

mysql初始化很慢_mysql初始化報錯

/var/log/mysql.log 日志報錯如上圖所示解決方法&#xff1a;SELinux惹的禍通俗的講就是linux服務器的安全策略解決&#xff1a;臨時關閉&#xff1a;setenforce 0永久關閉需要修改配置文件&#xff0c;重啟機器&#xff1a;修改/etc/selinux/config 文件將SELINUXenforcing改為…

百度java的線程技術_自我提升(基礎技術篇)——java線程簡介

前言&#xff1a;雖然自己平時都在用多線程&#xff0c;也能完成基本的工作需求&#xff0c;但總覺得&#xff0c;還是對線程沒有一個系統的概念&#xff0c;所以&#xff0c;查閱了一些資料&#xff0c;理解那些大神和官方的資料&#xff0c;寫這么一篇關于線程的文章本來想廢…

java調用掃描儀識別文字_Java使用掃描儀讀取文件輸入

示例Scanner scanner null;try {scanner new Scanner(new File("Names.txt"));while (scanner.hasNext()) {System.out.println(scanner.nextLine());}} catch (Exception e) {System.err.println("發生異常&#xff01;");} finally {if (scanner ! nul…

d3 tip mysql_mysql

字符&#xff1a;char(10)->定長、10個字符寬度。如果右側不夠&#xff0c;則空格補齊&#xff0c;取出來的時候刪除空格。varchar(10)->變長、最多10個字符如&#xff1a;存姓名的時候&#xff0c;沒必要為了那幾個長度去使用varchar&#xff0c;使用定長去存儲會提高效…

java string rt_如何使jvm加載我的java.lang.String而不是rt.jar中的那個

我認真研究了Java類加載器。現在&#xff0c;我想編寫一個與rt.jar中的類之一具有相同的包名稱和類名稱的類。例如&#xff0c;我自己編寫一個java.lang.String類&#xff0c;以及如何打破父級委托模型以使jvm加載我的java.lang.String而不是rt.jar中的類。重新編輯Thx&#xf…

php在線語音,PHP在線語音合成

這篇文章主要介紹了PHP在線語音合成&#xff0c;有著一定的參考價值&#xff0c;現在分享給大家&#xff0c;有需要的朋友可以參考一下在線語音合成 PHP SDKhttp://yuyin.baidu.com/docs/tts/194PHP SDK文檔簡介Hi&#xff0c;您好&#xff0c;歡迎使用百度語音合成服務。本文檔…

php工廠模式和單例模式,php 設計模式之工廠模式、單例模式、注冊樹模式

php 設計模式之工廠模式、單例模式、注冊樹模式在軟件工程中&#xff0c;創建型設計模式承擔著對象創建的職責&#xff0c;嘗試創建適合程序上下文的對象&#xff0c;對象創建設計模式的產生是由于軟件工程設計的問題&#xff0c;具體說是向設計中增加復雜度&#xff0c;創建型…

php 正則匹配unicode,PHP中正則表達式對UNICODE字符碼的匹配方法

網友ainiaa的問題是PHP代碼如下代碼如下:$words "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSRUVWXYZ!#$%^&*()_-[]\\,./{}|<>?\"你好啊我們";$otherStrpreg_replace("/[chr(128)-chr(256)]/is"," ",$words);ech…

iis7怎么安裝php7,Linux下如何安裝php7

Linux下安裝php7的方法&#xff1a;首先安裝依賴包&#xff0c;并下載解壓安裝包&#xff1b;然后檢查環境的依賴關系&#xff0c;并編譯安裝&#xff1b;接著將【php.ini-production】改名為【php.ini】&#xff1b;最后復制啟動腳本&#xff0c;并啟動PHP即可。Linux下安裝ph…

php長輪詢阻塞,ajax長輪詢時php被阻塞

剛接觸實時通訊這塊&#xff0c;知道用websocket更高效&#xff0c;但我想了解輪詢的實現過程&#xff0c;循序漸進短輪詢用定時器setInterval已經實現了&#xff0c;但長輪詢時后臺進入死循環模塊導致整個網站的php網頁無響應&#xff0c;比如刷新頁面、提交消息都沒法進行。具…

php隱藏路徑ngnix,thinkphp框架在nginx環境下去掉index.php路徑顯示

協助用戶將apache下的一個網站遷移到nginx環境中&#xff0c;結果發現用戶用的ThinkPHP框架做的開發&#xff0c;默認用的pathinfo。這是一個很頭疼的問題&#xff0c;因為nginx不支持pathinfo&#xff0c;貿然一并打開也擔心不安全。于是查詢資料后整理如下&#xff1a;找到ap…

php curl 數據采集 空,PHP curl從網站返回空數組的數據

我想寫一個PHP腳本來從www.snowbird.com/mountain-report/拉雪和其他數據通過LED陣列顯示。我在獲取需要的數據方面遇到麻煩。我似乎無法找到使其工作的方法。我能做這項工作嗎&#xff1f;還是我需要去使用另一種語言&#xff1f;PHP curl從網站返回空數組的數據以下代碼僅返回…

flux react php,Vue的Flux框架之Vuex狀態管理器

學習vue之前&#xff0c;最重要是弄懂兩個概念&#xff0c;一是“what”&#xff0c;要理解vuex是什么&#xff1b;二是“why”,要清楚為什么要用vuex。Vuex是什么&#xff1f;Vuex 類似 React 里面的 Redux 的狀態管理器&#xff0c;用來管理Vue的所有組件狀態。為什么使用Vue…

php config(),php config

PHP 的安裝由于php是一個zip文件(非install版)&#xff0c;安裝較為基本解壓就行。把解壓的 php5.2.1-Win32重命名為 php5。并復制到安裝盤目錄下。例如安裝路徑為 c:\php51 找到php目錄下的 php.ini-dist或 php.ini.recommended文件&#xff0c;重命名為 php.ini,并復制到系統…

functions.php 在哪,functions.php常用函數

在設計WordPress主題時&#xff0c;在functions.php文件里添加一套通用的自定義函數將會大大提高開發效率&#xff0c;這樣就不必每次開發主題時都需先查找然后復制同樣的函數。這里記錄一些常用的函數&#xff0c;方便以后使用&#xff01;給頭部添加feed鏈接WordPress2.8以后…

java基本數據類型存儲,JAVA - 基本數據類型的存儲空間長度

1.整型類型 存儲需求 bit數 取值范圍 備注byte 1字節 1*8 &#xff0d;128&#xff5e;127short 2字節 2*8 &#xff0d;32768&#xff5e;32767int 4字節 4*8 (-2的31次方到2的31次方-1)long 8字節 8*8 (-2的63次方到2的63次方-1) 長整型數值后綴為LJAVA 沒有無符號類型JAVA中…

matlab回調函數,matlabGUI回調函數介紹.pptx

matlabGUI回調函數介紹GUI開發環境的常用工具與回調函數和GUI程序文件GUI開發常用工具1、控件面板2、對象對齊工具3、對象瀏覽器4、tab順序編輯器5、屬性編輯器6、菜單編輯器7、M文件編輯器回調函數回調函數是控件接收到用戶的操作時調用的特定函數&#xff0c;每個回調函數都是…

余額交易查詢 php,深圳通余額查詢的API

深圳通余額查詢的API&#xff0c;可以通過深圳通號碼查詢到余額及卡有效期等信息。 用到Domxpath和Curl兩方面的知識。 源碼已托管到github&#xff0c;另外要加載個類&#xff1a;myclass 項目地址&#xff1a;https://github.com/skiy/dev 演示&#xff1a;http://api.oupag.…

食餌捕食者模matlab,幾類食餌-捕食者模型的定性分析和數值模擬

摘要&#xff1a;生態問題一直是人們普遍關注的問題,特別是生態問題中的食餌-捕食者模型,則處于舉足輕重的位置。如何更有效的控制、調節生物種群,使之保持良性發展,則具有非常重要的生態意義和應用價值。解決這類問題的主要工具是種群動力學模型,解決的依據是數學的理論和方法…

數組填充php,php數組入門教程之數組填充

本文介紹下&#xff0c;有關php數組之數組填充的一個例子&#xff0c;有需要的朋友參考下。在php編程中&#xff0c;對數組元素進行填充&#xff0c;可以使用array_fill()函數。來看下面的例子&#xff0c;array_fill()函數——填充數組函數&#xff1a;";print_r ($array…