摘要:獲取每個元素的字符串長度放入新流中,然后轉為類型。歸約歸約就是把整個流歸約成一個值的操作,比如求集合中最大的元素所有元素值的和之類的操作。
前言:
上一篇文章 Java 8之stream介紹和使用 中講解了stream的定義和用法,簡單介紹幾個最基本最常用的方法,其實stream還有更強大的功能,這篇文章就會給大家介紹stream的進階用法。
篩選:在上一篇文章中我們介紹了使用filter方法來篩選元素,filter方法接受一個Predicate類型的參數,我們可以傳入一個Lamada表達式或者方法引用,原理在 Java 8之方法引用和Lambda表達式 中已經將結果。我們實際上是傳入了一個條件,然后篩選出符合條件的元素,例如下面的這行代碼就是篩選出年齡大于20的人。
Listlist = peoples.stream().filter(person -> person.getAge()>20).collect(toList());
實際上stream還有別的方法可以進行篩選,下面我們來介紹幾個常用的。
distinct,這個方法可以幫助我們去重
Listnumbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4); numbers.stream().filter(i -> i % 2 == 0).distinct().forEach(System.out::println);
limit,這個方法可以讓我們只取stream中的前幾個,值得注意的是當我們用Set集合來存儲元素時,因為Set是無序的,所以每次我們取到的前幾個元素也會是無序的。
Listnumbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4); numbers.stream().limit(3).forEach(System.out::println);
skip,這個方法可以讓我們跳過元素,跳過多少個元素由我們指定。
List映射:numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4); numbers.stream().skip(3).forEach(System.out::println);
我們經常遇到從對象中抽取自己需要的元素放入一個新的類型的集合中的情況,這就是映射操作,而stream在這方面也提供了非常強大的支持。
map,這個方法接受一個Lambda表達式,它會遍歷整個流把這個函數作用到每個元素上,然后把輸出的結果放到一個新流中。
// 獲取每個元素的name屬性放入一個新流中,然后把這個流轉為List類型。 Listnames = peoples.stream().map(Person::getName).collect(toList()); // 獲取每個元素的字符串長度放入新流中,然后轉為List類型。 List words = Arrays.asList("AA", "B", "CCC", "DDDDDD"); List wordLengths = words.stream().map(String::length).collect(toList());
flatmap,這個方法比較特殊,它的作用是把多個相同類型的流連成一個流,我們看下面的代碼,目的是為了把集合中的字符串都拆成單個字符然后放到一個集合,但是如果直接用map方法的話返回的List是String[]類型的,這是因為word.split("")返回的結果就是這個類型的。
Listwords = Arrays.asList("Hello", "world"); List list = words.stream().map(word -> word.split("")).collect(toList());
在這里要提到Arrays.stream()這個方法,它的作用是接受一個數組,然后把這個數組里的元素轉為一個流,所以我們可以嘗試使用這個方法來改進下上面的代碼。但是我們發現還是有問題,返回集合類型是Stream
Listwords = Arrays.asList("Hello", "world"); List > list = words.stream().map(word -> word.split("")) .map(Arrays::stream).collect(toList());
現在flatmap的作用就出來了,我們把代碼改進下,改成使用flatmap接受Arrays::stream,它的作用正是在上面map(Arrays::stream)的基礎上把集合里的流里面的元素合并成一個流,所以返回的List類型就是String類型的。
List匹配:words = Arrays.asList("Hello", "world"); List list = words.stream().map(word -> word.split("")) .flatmap(Arrays::stream).collect(toList());
stream同樣也提供了很多方法來檢查集合中是否包含了某個指定的值。注意,這些方法都屬于 終端操作 ,也就是說調用了這些方法就會關閉流。
allMatch
Listnumbers = Arrays.asList("Hello", "World"); boolean flag = numbers.stream().allMatch(string -> string.contains("z")); System.out.println(flag);
anyMatch,這個方法會檢查流中是否至少有一個元素匹配給定的值,返回一個boolean值。
Listnumbers = Arrays.asList("Hello", "World"); boolean flag = numbers.stream().anyMatch(string -> string.contains("z")); System.out.println(flag);
noneMatch,這個方法則是和allMatch方法做相反的操作。
List查找:numbers = Arrays.asList("Hello", "World"); boolean flag = numbers.stream().noneMatch(string -> string.contains("z")); System.out.println(flag);
對于集合的操作最重要的就是從中查找符合條件的數據了,我們來看下面的方法。
findAny,這個方法需要配合filter方法使用,返回把篩選出來的第一個元素。注意,這里返回的是Optional類型的對象,這個對象是Java 8新增的專門為了防止返回數據的時候遇到null的情況,后續再作詳細了解,目前只需要知道它有個isPresent方法來判斷元素是否為空,get方法用來取值。
Listnumbers = Arrays.asList("Hello", "World"); Optional optional= numbers.stream().filter(string -> string.contains("l")).findAny(); if(optional.isPresent()){ System.out.println(optional.get()); }
findFirst,這個方法是用來取流中第一個元素的,目前看來好像沒什么用,但是有時候我們可能會對流進行復雜的篩選,再選取篩選后的流中第一個元素。
List歸約:numbers = Arrays.asList("Hello", "World"); Optional optional= numbers.stream().findFirst(); System.out.println(optional.toString());
歸約就是把整個流歸約成一個值的操作,比如求集合中最大的元素、所有元素值的和之類的操作。
reduce,這個方法就是用來對元素的值進行操作的,我們這里做加法運算。它接受兩個參數,第一個是初始值,就是開始計算前就已經有一個數值了。第二個參數是一個Lambda表達式,用來對各個元素做計算。
Listlist = Arrays.asList(1,2,3,4,5); int sum = list.stream().reduce(0,(a,b) -> a - b); System.out.println(sum);
在Java 8中Integer中新增了一個sum方法,它的作用和上面的Lambda表達效果一樣,所以我們可以使用這個方法的方法引用來簡化代碼。
Listlist = Arrays.asList(1,2,3,4,5); int sum = list.stream().reduce(0,Integer::sum); System.out.println(sum);
我們還可以用這個方法來求最大值和最小值,在Integer中還新增了min、max方法,等同于(x, y) -> x < y ? x : y、(x, y) -> x > y ? x : y,這樣我們就可以求出流中的最大值和最小值了。
Optionalmin = numbers.stream().reduce(Integer::min); Optional min = numbers.stream().reduce(Integer::max);
以上就是stream的篩選、查找、匹配和歸約操作中比較常用的方法了,下面還會介紹分組、分區等功能。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/76554.html
摘要:前言在前面的之介紹和使用和之進階中講了的使用方式和一些常用的方法,這篇文章就來演示一下的實際應用。實際應用先創建一個訂單類和商品類,每個訂單都有年份商品數量和商品對象屬性,而商品類里面則包含了名字和價格屬性。 前言: 在前面的 Java 8之stream介紹和使用 和 Java 8之stream進階 中講了stream的使用方式和一些常用的方法,這篇文章就來演示一下stream的實際應...
摘要:方法接收的是的實例,但是它沒有返回值方法是函數式接口,無參數,會返回一個結果這兩個方法是的升級,表示讓任務在指定的線程池中執行,不指定的話,通常任務是在線程池中執行的。該的接口是在線程使用舊的接口,它不允許返回值。 簡介 作為Java 8 Concurrency API改進而引入,本文是CompletableFuture類的功能和用例的介紹。同時在Java 9 也有對Completab...
以下是Java技術棧微信公眾號發布的關于 Java 的技術干貨,從以下幾個方面匯總。 Java 基礎篇 Java 集合篇 Java 多線程篇 Java JVM篇 Java 進階篇 Java 新特性篇 Java 工具篇 Java 書籍篇 Java基礎篇 8張圖帶你輕松溫習 Java 知識 Java父類強制轉換子類原則 一張圖搞清楚 Java 異常機制 通用唯一標識碼UUID的介紹及使用 字符串...
摘要:導讀閱讀本文需要有足夠的時間,筆者會由淺到深帶你一步一步了解一個資深架構師所要掌握的各類知識點,你也可以按照文章中所列的知識體系對比自身,對自己進行查漏補缺,覺得本文對你有幫助的話,可以點贊關注一下。目錄一基礎篇二進階篇三高級篇四架構篇五擴 導讀:閱讀本文需要有足夠的時間,筆者會由淺到深帶你一步一步了解一個資深架構師所要掌握的各類知識點,你也可以按照文章中所列的知識體系對比自身,對自己...
閱讀 1123·2023-04-26 00:12
閱讀 3249·2021-11-17 09:33
閱讀 1061·2021-09-04 16:45
閱讀 1186·2021-09-02 15:40
閱讀 2146·2019-08-30 15:56
閱讀 2951·2019-08-30 15:53
閱讀 3548·2019-08-30 11:23
閱讀 1932·2019-08-29 13:54