日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java8函数式编程 视频_快速掌握Java8 Stream函数式编程技巧

發布時間:2025/4/5 java 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java8函数式编程 视频_快速掌握Java8 Stream函数式编程技巧 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

函數式編程優勢“函數第一位”,即函數可以出現在任何地方。

可以把函數作為參數傳遞給另一個函數,還可以將函數作為返回值。

讓代碼的邏輯更清晰更優雅。

減少了可變量(Immutable Variable)的聲明,程序更為安全。

支持惰性計算。

Lambda語法三部分一個括號內用逗號分隔的形式參數,參數是函數式接口里面方法的參數

一個箭頭符號:->

方法體,可以是表達式和代碼塊,方法體函數式接口里面方法的實現,如果是代碼塊,則必須用{}來包裹起來,且需要一個return 返回值,但有個例外,若函數式接口里面方法返回值是void,則無需{}。例如:

(parameters) -> expression 或者 (parameters) -> { statements; }

方法引用是lambda表達式的一個簡化寫法,所引用的方法其實是lambda表達式的方法體實現,語法也很簡單,左邊是容器(可以是類名,實例名),中間是“::”,右邊是相應的方法名。如下所示:

ObjectReference::methodName

一般方法的引用格式是:如果是靜態方法,則是ClassName::methodName。如 Object ::equals

如果是實例方法,則是Instance::methodName。如Object obj=new Object();obj::equals;

構造函數.則是ClassName::new

Stream是什么

Stream是Java8中新加入的api,更準確的說: Java 8 中的 Stream 是對集合(Collection)對象功能的增強,它專注于對集合對象進行各種非常便利、高效的聚合操作,或者大批量數據操作 。Stream API 借助于同樣新出現的 Lambda 表達式,極大的提高編程效率和程序可讀性。

?

以前我們處理復雜的數據只能通過各種for循環,不僅不美觀,而且時間長了以后可能自己都看不太明白以前的代碼了,但有Stream以后,通過filter,map,limit等等方法就可以使代碼更加簡潔并且更加語義化。 Stream的效果就像上圖展示的它可以先把數據變成符合要求的樣子(map),吃掉不需要的東西(filter)然后得到需要的東西(collect)。

Stream操作分類

Stream上的所有操作分為兩類:中間操作和結束操作,中間操作只是一種標記,只有結束操作才會觸發實際計算。中間操作又可以分為無狀態的(Stateless)和有狀態的(Stateful),無狀態中間操作是指元素的處理不受前面元素的影響,而有狀態的中間操作必須等到所有元素處理之后才知道最終結果,比如排序是有狀態操作,在讀取所有元素之前并不能確定排序結果;結束操作又可以分為短路操作和非短路操作,短路操作是指不用處理全部元素就可以返回結果,比如找到第一個滿足條件的元素。之所以要進行如此精細的劃分,是因為底層對每一種情況的處理方式不同。

Stream API等價實現

求出字符串集合中所有以字母A開頭字符串的最大長度

int longest = 0;

for(String str : strings){

if(str.startsWith("A")){// 1. filter(), 保留以A開頭的字符串

int len = str.length();// 2. mapToInt(), 轉換成長度

longest = Math.max(len, longest);// 3. max(), 保留最長的長度

}

}

int longest = strings.stream()

.filter(str -> str.startsWith("A"))

.mapToInt(str -> str.length())

//.mapToInt(String::length)

.max();

Stream串行與并行

Stream可以分為串行與并行兩種,串行流和并行流差別就是單線程和多線程的執行。 default Stream stream() : 返回串行流 default Stream parallelStream() : 返回并行流 stream()和parallelStream()方法返回的都是java.util.stream.Stream類型的對象,說明它們在功能的使用上是沒差別的。唯一的差別就是單線程和多線程的執行。

Stream性能總結

1.對于簡單操作,比如最簡單的遍歷,Stream串行API性能明顯差于顯示迭代,但并行的Stream API能夠發揮多核特性。

2.對于復雜操作,Stream串行API性能可以和手動實現的效果匹敵,在并行執行時Stream API效果遠超手動實現。

所以,如果出于性能考慮:對于簡單操作推薦使用外部迭代手動實現。

對于復雜操作,推薦使用Stream API。

在多核情況下,推薦使用并行Stream API來發揮多核優勢。

單核情況下不建議使用并行Stream API。 如果出于代碼簡潔性考慮,使用Stream API能夠寫出更短的代碼。即使是從性能方面說,盡可能的使用Stream API也另外一個優勢,那就是只要Java Stream類庫做了升級優化,代碼不用做任何修改就能享受到升級帶來的好處。

Stream 來源

所有流計算都有一種共同的結構:它們具有一個流來源、0 或多個中間操作,以及一個終止操作。流的元素可以是對象引用 (Stream),也可以是原始整數 (IntStream)、長整型 (LongStream) 或雙精度 (DoubleStream)。

因為 Java 程序使用的大部分數據都已存儲在集合中,所以許多流計算使用集合作為它們的來源。JDK 中的 Collection 實現都已增強,可充當高效的流來源。但是,還存在其他可能的流來源,比如數組、生成器函數或內置的工廠(比如數字范圍),而且可以編寫自定義的流適配器,以便可以將任意數據源充當流來源。如上圖中一些流生成方法。

Stream 操作

中間操作負責將一個流轉換為另一個流,中間操作包括 filter()(選擇與條件匹配的元素)、map()(根據函數來轉換元素)、distinct()(刪除重復)、limit()(在特定大小處截斷流)和 sorted()。一些操作(比如 mapToInt())獲取一種類型的流并返回一種不同類型的流。

中間操作始終是惰性的:調用中間操作只會設置流管道的下一個階段,不會啟動任何操作。重建操作可進一步劃分為無狀態 和有狀態 操作。無狀態操作(比如 filter() 或 map())可獨立處理每個元素,而有狀態操作(比如 sorted() 或 distinct())可合并以前看到的影響其他元素處理的元素狀態。

數據集的處理在執行終止操作時開始,比如縮減(sum() 或 max())、應用 (forEach()) 或搜索 (findFirst()) 操作。終止操作會生成一個結果或副作用。執行終止操作時,會終止流管道,如果您想再次遍歷同一個數據集,可以設置一個新的流管道。如下給出了一些終止流操作。

Stream 流與集合比較

集合是一種數據結構,它的主要關注點是在內存中組織數據,而且集合會在一段時間內持久存在。 流的關注點是計算,而不是數據。流沒有為它們處理的元素提供存儲空間,而且流的生命周期更像一個時間點 — 調用終止操作。 不同于集合,流也可以是無限的(Stream.generate、Stream.iterate);相應地,一些操作(limit()、findFirst())是短路,而且可在無限流上運行有限的計算。 程序 = 數據結構 + 算法,集合即數據結構,流操作相當于算法。

數據形式:集合是一個內存中的數據結構,它包含數據結構中目前所有的值——集合中的每個元素都得先算出來才能添加到集合中。(你可以往集合里加東西或者刪東西,但是不管什么時候,集合中的每個元素都是放在內存里的,元素都得先算出來才能成為集合的一部分。) 相比之下,流則是在概念上固定的數據結構(你不能添加或刪除元素),其元素則是按需計算的。

迭代方式:使用Collection接口需要用戶去做迭代(比如用for-each),這稱為外部迭代。相反,Streams庫使用內部迭代——它幫你把迭代做了,還把得到的流值存在了某個地方,你只要給出一個函數說要干什么就可以了。Steams庫的內部迭代可以自動選擇一種適合你硬件的數據表示和并行實現。

Stream 基本使用

filter篩選(中間操作)

輸出:4,5

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

Stream stream = integerList.stream().filter(i -> i > 3);

distinct去重(中間操作)

輸出:1,2,3,4,5

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

Stream stream = integerList.stream().distinct();

limit限制(中間操作)

輸出:1,1,2

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

Stream stream = integerList.stream().limit(3);

skip跳過(中間操作)

輸出:2,3,4,5

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

Stream stream = integerList.stream().skip(2);

map流映射(中間操作)

輸出:6, 7, 2, 6

List stringList = Arrays.asList("Java 8", "Lambdas", "In", "Action");

Stream stream = stringList.stream().map(String::length);

flatMap流轉換(中間操作)

輸出:1, 2, 3, 4

將一個流中的每個值都轉換為另一個流

List> lists = new ArrayList>() {{

add(Arrays.asList(1, 2));

add(Arrays.asList(3, 4));

}};

Stream stream = lists.stream().flatMap(List::stream);

//Stream stream = lists.stream().flatMap(list -> list.stream());

allMatch匹配所有(中間操作)

輸出:

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

if (integerList.stream().allMatch(i -> i > 3)) {

System.out.println("值都大于3");

}

noneMatch全部不匹配(中間操作)

輸出:

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

if (integerList.stream().noneMatch(i -> i > 3)) {

System.out.println("值都小于3");

}

anyMatch匹配其中一個(中間操作)

輸出:存在大于3的值

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

if (integerList.stream().anyMatch(i -> i > 3)) {

System.out.println("存在大于3的值");

}

findFirst查找第一個(終端操作)

輸出:4

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

Optional result = integerList.stream().filter(i -> i > 3).findFirst();

findAny隨機查找一個(終端操作)

輸出:存在大于3的值

和findFirst操作相比,并行流優勢更大

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

if (integerList.stream().findAny(i -> i > 3)) {

System.out.println("存在大于3的值");

}

Stream 常用統計

List ints = Arrays.asList(1, 1, 2, 2, 3);

//統計流中元素個數

ints.stream().count();

ints.stream().collect(Collectors.counting());

//獲取流中最小值

ints.stream().min(Integer::compareTo);

ints.stream().collect(Collectors.minBy(Integer::compareTo));

//獲取流中最大值

ints.stream().max(Integer::compareTo);

ints.stream().collect(Collectors.maxBy(Integer::compareTo));

//求和

ints.stream().mapToInt(Integer::intValue).sum();

ints.stream().collect(Collectors.summingInt(Integer::intValue));

ints.stream().reduce(0, Integer::sum);

//平均值

ints.stream().collect(Collectors.averagingInt(Integer::intValue));

//通過summarizingInt同時求總和、平均值、最大值、最小值

ints.stream().collect(Collectors.summarizingInt(Integer::intValue));

Stream 終端操作(collect)

List ints = Arrays.asList(1, 1, 2, 2, 3);

//返回List

ints.stream().collect(Collectors.toList());

//返回Set

ints.stream().collect(Collectors.toSet());

//返回Map

ints.stream().collect(Collectors.toMap(k -> k, v -> v, (v1, v2) -> v1));

//group分組

ints.stream().collect(Collectors.groupingBy(k -> k));

//partitioningBy分區

ints.stream().collect(Collectors.partitioningBy(k -> k % 2 == 0));

Stream參考文獻

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的java8函数式编程 视频_快速掌握Java8 Stream函数式编程技巧的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。