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