Java詳細(xì)分析Lambda表達(dá)式與Stream流的使用方法
Lambda
Lambda 表達(dá)式是一個匿名函數(shù),我們可以把 lambda 表達(dá)式理解為一段可以傳遞的代碼(將代碼段像數(shù)據(jù)一樣傳遞)。使用它可以寫出更簡潔, 更靈活的代碼。作為一種更緊湊的代碼風(fēng)格,使 java 語言的表達(dá)式能力得到的提升。
我們可以知道, Lambda表達(dá)式是為簡化語法而存在的
ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); list.sort(new Comparator<String>() { @Override public int compare(String o1, String o2) { return o2.compareTo(o1); } }); System.out.println(list);
這里有一個List集合 , 并添加了一些元素, 我們想對他進(jìn)行排序, 并且按照降序的方式來排 , 在沒接觸Lambda表達(dá)式之前 ,我們是向上面那樣去做的
上面這種方式是匿名內(nèi)部類寫法 , 調(diào)用sort()方法時, 要求傳入一個比較器, Comparator是一個接口, 接口可以new嗎? 肯定是不能的 , 所以這里是有一個隱藏的類去實現(xiàn)了Comparator接口, 并且重寫了它里面的compare()方法 , 來制定我們的比較規(guī)則, 這個隱藏的類沒有類名, 就是我們這里所說的匿名內(nèi)部類 , 但方法也是不能作為參數(shù)去傳遞的, 所以我們new了這個匿名內(nèi)部類的對象 , 包裹了實現(xiàn)后的方法
但是現(xiàn)在我們嫌這個寫法太啰嗦了 ,我們使用Lambda來看看
// Lambda表達(dá)式 list.sort((o1,o2) -> {return o2.compareTo(o1);});
這就和上面的匿名內(nèi)部類寫法是一樣的
Lambda表達(dá)式的結(jié)構(gòu) :
左側(cè):lambda 表達(dá)式的參數(shù)列表
右側(cè):lambda 表達(dá)式中需要執(zhí)行的功能,即 lambda 體
(arg1, arg2...) -> { body }
(type1 arg1, type2 arg2...) -> { body }
常見例子
無參數(shù),無返回值,lambda 體中只有一行代碼時,{}可以忽略 () -> System.out.println("Hello World");
無參數(shù),有返回值 () -> { return 3.1415 };
有參數(shù),無返回值 (String s) -> { System.out.println(s); }
有一個參數(shù),無返回值 s -> { System.out.println(s); }
有多個參數(shù),有返回值 (int a, int b) -> { return a + b; }
有多個參數(shù),表達(dá)式參數(shù)類型可以不寫,jvm 可以根據(jù)上下文進(jìn)行類型推斷 (a, b) -> { return a - b; }
功能接口
功能接口上面一般會有這樣一個注解標(biāo)簽@FunctionalInterface , 它表示此接口只有一個抽象方法, 當(dāng)你注釋的接口違反了 Functional Interface 的契約時,它可以用于編譯器級錯誤
例如 : 我們剛使用的comparator接口就有這樣的注解
Stream流
允許你以聲明式的方式處理數(shù)據(jù)集合,可以把 它看作是遍歷數(shù)據(jù)集的高級迭代器。此外與 stream 與 lambada 表達(dá)示結(jié)合后 編碼效率與大大提高,并且可讀性更強(qiáng)。
流更偏向于數(shù)據(jù)處理和計算,比如 filter、map、find、sort 等。簡單來說,我們通過一個集合的 stream 方法獲取一個流,然后對流進(jìn)行一 系列流操作,最后再構(gòu)建成我們需要的數(shù)據(jù)集合。
我們常常將Stream流與Lambda表達(dá)式結(jié)合來編碼 , 那么如何來使用呢 ?
這里分為 3 步 :
1. 獲得流
2. 中間操作
3. 終端操作
中間操作(往往對數(shù)據(jù)進(jìn)行篩選)
- filter:過濾流中的某些元素,
- sorted(): 自然排序,流中元素需實現(xiàn) Comparable 接口
- distinct: 去除重復(fù)元素
- limit(n): 獲取 n 個元素
- skip(n): 跳過 n 元素,配合 limit(n)可實現(xiàn)分頁
- map(): 將其映射成一個新的元素
終端操作(往往對結(jié)果集進(jìn)行處理)
- forEach: 遍歷流中的元素
- toArray:將流中的元素倒入一個數(shù)組
- Min:返回流中元素最小值 Max:返回流中元素最大值
- count:返回流中元素的總個數(shù)
- Reduce:所有元素求和
- anyMatch:接收一個 Predicate 函數(shù),只要流中有一個元素滿足條件則返回 true,否則返回
- falseallMatch:接收一個 Predicate 函數(shù),當(dāng)流中每個元素都符合條件時才返回 true,否則返回 false
- findFirst:返回流中第一個元素
- collect:將流中的元素倒入一個集合,Collection 或 Map
Integer[] arr = new Integer[]{1,4,3,2,5,5}; Arrays.stream(arr) //拿到流 .filter((a) -> {return a>3;}) //中間操作,過濾 .forEach((a) -> { //終端操作,遍歷 System.out.println(a); }); Integer[] arr = new Integer[]{1,4,3,2,5,5}; Object[] objects = Arrays.stream(arr) .sorted().distinct() //排序并去重 .toArray(); //轉(zhuǎn)數(shù)組 System.out.println(Arrays.toString(objects)); Integer[] arr = new Integer[]{1,4,3,2,5,5}; Integer max = Arrays.stream(arr).distinct() .max(((o1, o2) -> { //去重返回最大值 return o1 - o2; })).get(); //拿到這個值 //此處max為終端操作,返回的已經(jīng)不是流,而是一個OPtion的對象 //它里面有一個get()方法可以返回這個值 System.out.println(max); Integer[] arr = new Integer[]{1,4,3,2,5,5}; long count = Arrays.stream(arr).distinct() .count(); //返回總個數(shù) System.out.println(count); Integer[] arr = new Integer[]{1,4,3,2,5,5}; Integer i = Arrays.stream(arr).distinct() .reduce((o1, o2) -> { //所有元素求和 return o1 + o2; }) .get(); System.out.println(i);
這里需要注意的是中間操作的map()方法和終端操作的collect()方法
設(shè)計一個Apple類
public class Apple { private Integer num; private String name; private String color; }
并給出 構(gòu)造 , set 和 get 方法 ,此處由于篇幅 原因省略
List<Apple> list = new ArrayList<>(); list.add(new Apple(100,"蘋果1","紅色")); list.add(new Apple(105,"蘋果5","紅色")); list.add(new Apple(104,"蘋果4","紅色")); list.add(new Apple(103,"蘋果3","紅色")); list.add(new Apple(102,"蘋果2","紅色"));
往一個list添加5個元素
List<String> collect = list.stream() //將屬性的一列通過get方法映射成流 .map(Apple::getName) //轉(zhuǎn)為一個list集合 .collect(Collectors.toList()); System.out.println(collect); List<Apple> collect = list.stream().sorted(((o1, o2) -> { //通過num屬性自定義排序 return o1.getNum() - o2.getNum(); })) //轉(zhuǎn)為一個list集合 .collect(Collectors.toList()); System.out.println(collect); Map<Integer, String> map = list.stream().sorted(((o1, o2) -> { return o1.getNum() - o2.getNum(); })) //轉(zhuǎn)map, 第一個參數(shù)為鍵,第二個參數(shù)為值 .collect(Collectors.toMap(Apple::getNum, Apple::getName)); System.out.println(map);
到此關(guān)于Lambda表達(dá)式與Stream流就介紹完了,感謝閱讀
到此這篇關(guān)于Java詳細(xì)分析Lambda表達(dá)式與Stream流的使用方法的文章就介紹到這了,更多相關(guān)Java Lambda與Stream內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 一文帶你徹底了解Java8中的Lambda,函數(shù)式接口和Stream
- Java的Lambda表達(dá)式和Stream流的作用以及示例
- Java分析Lambda表達(dá)式Stream流合并分組內(nèi)對象數(shù)據(jù)合并
- Java中的lambda和stream實現(xiàn)排序
- 吊打Java面試官之Lambda表達(dá)式 Stream API
- Java8中Lambda表達(dá)式使用和Stream API詳解
- 詳解Java遞歸實現(xiàn)樹形結(jié)構(gòu)的兩種方式
- Java實現(xiàn)樹形結(jié)構(gòu)的示例代碼
- Java樹形結(jié)構(gòu)數(shù)據(jù)生成導(dǎo)出excel文件方法記錄
- Java使用 Stream 流和 Lambda 組裝復(fù)雜父子樹形結(jié)構(gòu)
相關(guān)文章
Java?spring?boot實現(xiàn)批量刪除功能詳細(xì)示例
這篇文章主要給大家介紹了關(guān)于Java?spring?boot實現(xiàn)批量刪除功能的相關(guān)資料,文中通過代碼以及圖文將實現(xiàn)的方法介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2023-08-08java HashMap,TreeMap與LinkedHashMap的詳解
這篇文章主要介紹了 java HashMap,TreeMap與LinkedHashMap的詳解的相關(guān)資料,這里提供實例代碼,幫助大家學(xué)習(xí)理解 這部分的內(nèi)容,需要的朋友可以參考下2016-11-11POI導(dǎo)出之Excel實現(xiàn)單元格的背景色填充問題
這篇文章主要介紹了POI導(dǎo)出之Excel實現(xiàn)單元格的背景色填充問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03springcloud使用profile實現(xiàn)多環(huán)境配置方式
這篇文章主要介紹了springcloud使用profile實現(xiàn)多環(huán)境配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03IDEA2020.1啟動SpringBoot項目出現(xiàn)java程序包:xxx不存在
這篇文章主要介紹了IDEA2020.1啟動SpringBoot項目出現(xiàn)java程序包:xxx不存在,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06