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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

stream distinct去重_再来看看Java的新特性——Stream流

發(fā)布時間:2025/1/21 java 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 stream distinct去重_再来看看Java的新特性——Stream流 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

半年前開始試著使用Java的新特性,給我印象最深的就是Stream流和Optional。其中Stream提高了看法效率,讓代碼看起來十分清爽。

為什么要使用流?

摘要中已經(jīng)說明了,為了提高開發(fā)效率。流可以幫助我們高效操作集合,流幫助我們通過流水線的方式對集合進行刪減、合并、排序、修改,并最終返回我們想要的元素數(shù)據(jù)或統(tǒng)計數(shù)據(jù)。流水線的意思是說,一批元素不需要等待全部元素都完成某步操作,才進行下步操作,而是可以盡早進行下步操作,就好像流水線工廠一樣,這為流高效運作提供了基礎(chǔ)。流還有一個內(nèi)部迭代的概念,就是把for循環(huán)顯示迭代隱藏起來了,這樣可以更方便的并行開發(fā)。

流的使用

準(zhǔn)備

在使用流之前需要做些準(zhǔn)備,首先說明兩個概念:中間操作 和 終端操作。中間操作就好比生產(chǎn)車間的一步一步元素處理,每步處理之后,里面的元素樣式或者數(shù)據(jù)結(jié)構(gòu)可能發(fā)生改變了,但是它還是流。終端操作就好比產(chǎn)品生產(chǎn)完了,要打包裝箱,變成最終消費者可見的最終形態(tài),此時,它已經(jīng)是產(chǎn)品,不再是流了。

接著為了演示操作,先模擬幾條數(shù)據(jù)

List<JSONObject> menu = new ArrayList<>(); menu.add(new JSONObject().putOpt("name","宮保雞丁").putOpt("price","28")); menu.add(new JSONObject().putOpt("name","魚香肉絲").putOpt("price","30")); menu.add(new JSONObject().putOpt("name","肉夾饃").putOpt("price","6")); menu.add(new JSONObject().putOpt("name","煎餅").putOpt("price","6"));

常用的中間操作

filter

filter應(yīng)該是Stream操作里面最常見的了,過濾器顧名思義就是過濾數(shù)據(jù)用的,filter的參數(shù)可以是lambda表達式。

//比如下面這句話,就是得到所有價格小于10的食物,得到的還是流。 //stream()方法將集合轉(zhuǎn)成流 menu.stream().filter(jsonObject -> jsonObject.getInt("price")<10);

distinct 、 limit 和 skip

distinct是去重,limit是截取前幾個元素,skip是跳過前多少個元素。

List<Integer> integerList = new ArrayList<>(); integerList.add(1); integerList.add(1); integerList.add(2); integerList.add(3); integerList.stream().distinct()//經(jīng)過去重,流還剩1、2、3.skip(1)//跳過第一個元素,流中還有2、3.limit(1);//截取第一個元素,流中還剩2

map

map映射,上面的filter是將元素篩選,map則是改變元素的樣式。比如,我們想要知道所有小于10塊食物的名字。

menu.stream().filter(jsonObject -> jsonObject.getInt("price")<10)//此時還是jsonObject.map(jsonObject -> jsonObject.getStr("name"));//此時變成了String

flatMap

流的合并,可以將多個數(shù)組合并操作,這樣返回元素不是流,而是具體元素本身了。

Stream.of(menu,foreignMenu)//此時元素是流 List<Stream>.flatMap(x -> x.stream())//此時元素是jsonObject List<jsonObject>.map(jsonObject -> jsonObject.getStr("name")).distinct();

常用的終端方法

allMatch、anyMatch、noneMatch、findFirst和findAny

ble data-draft-node="block" data-draft-type="table" data-size="normal" data-row-style="normal">//前三個方法都是返回boolean類型 boolean allMatchBool = menu.stream().allMatch(jsonObject -> jsonObject.getInt("price") < 10); boolean noneMatchBool = menu.stream().noneMatch(jsonObject -> jsonObject.getInt("price") < 10); boolean anyMatchBool = menu.stream().anyMatch(jsonObject -> jsonObject.getInt("price") < 10);

上面?zhèn)€方法返回的都是boolean類型,findFirst、findAny返回的都是元素。

//關(guān)于Optional,先不關(guān)心,總之是元素就對了 Optional<JSONObject> first = menu.stream().findFirst(); Optional<JSONObject> any = menu.stream().findAny();System.out.println(first.get().toString()); System.out.println(any.get().toString());//輸出 //{"price":"28","name":"宮保雞丁"} //{"price":"28","name":"宮保雞丁"}

以上兩個方法,只要找到符合條件的數(shù)據(jù),流就提前結(jié)束了。為什么都是輸出第一個元素,卻要實現(xiàn)有兩個方法呢?因為并行,findAny在并行方面限制會少一些。

reduce

最開始的時候說了,最終的返回值可以是元素集合,也可以是統(tǒng)計數(shù)據(jù)(或者說歸納),比如說元素求和。假設(shè)我們需要menu中所有食品各要一份需要花多少錢。

Optional<Integer> price = menu.stream()//List<JsonObject>.map(jsonObject -> jsonObject.getInt("price"))//先將元素轉(zhuǎn)成數(shù)字List<Integer>.reduce((x, y) -> x + y); System.out.println(price.get());

max和min

這個好理解,就是最大值和最小值嘛。效果類似于

.reduce(Integer::max) .reduce(Integer::min)

常用流匯總

其中沒有展示sorted、count這個都好理解。至于collect這個后面講,用的比較多。

流的轉(zhuǎn)化

除了對象流(Stream)以外,還有一些類型流,比如說 IntStream(以 IntStream 舉例,其他類似)上面求和返回的是Optional對象,那可以直接返回Integer類型嗎?

//使用映射方法mapToInt()就ok了 int price = menu.stream()//Stream.mapToInt(jsonObject -> jsonObject.getInt("price"))//IntStream.sum(); //類型流轉(zhuǎn)化回對象流,可以使用boxed() IntStream intStream = menu.stream().mapToInt(jsonObject -> jsonObject.getInt("price")); Stream<Integer> boxed = intStream.boxed(); //當(dāng)然了IntStream中有很多int類型操作的方法,就不一一舉例了,源碼打開一看,見名知意

收集器

前面講的常用的中間操作,返回值都是流,還有一些中斷操作,返回值都是Optional或者數(shù)值。可別忘了Stream最開始的初衷是為了解決集合操作問題。最終轉(zhuǎn)化成集合使用的中斷操作collect,參數(shù)是接口 Collector,里面有眾多轉(zhuǎn)化方法。

轉(zhuǎn)換成集合

最常用的莫非toList() 這個方法了,將返回結(jié)果變成List。

List<JSONObject> list = menu.stream().filter(jsonObject -> jsonObject.getInt("price") < 10).collect(Collectors.toList()); //當(dāng)然還有toSet()等等,觸類旁通

字符串拼接

比較常用,就是字符串鏈接了。使用joining()方法

String s = menu.stream().filter(jsonObject -> jsonObject.getInt("price") < 10).map(jsonObject -> jsonObject.getStr("name")).collect(Collectors.joining(","));

分組

根據(jù)提供的屬性分組,使用 groupingBy() ,為了方便說明,給上面各種食品一個type值:

List<JSONObject> menu = new ArrayList<>(); menu.add(new JSONObject().putOpt("name","宮保雞丁").putOpt("price","28").putOpt("type","good")); menu.add(new JSONObject().putOpt("name","魚香肉絲").putOpt("price","30").putOpt("type","good")); menu.add(new JSONObject().putOpt("name","肉夾饃").putOpt("price","6").putOpt("type","normal")); menu.add(new JSONObject().putOpt("name","煎餅").putOpt("price","6").putOpt("type","normal"));Map<String, List<JSONObject>> type = menu.stream().collect(Collectors.groupingBy(jsonObject -> jsonObject.getStr("type"))); System.out.println(type); //輸出 //{normal=[{"price":"6","name":"肉夾饃","type":"normal"}, {"price":"6","name":"煎餅","type":"normal"}], good=[{"price":"28","name":"宮保雞丁","type":"good"}, {"price":"30","name":"魚香肉絲","type":"good"}]}

與分組類似的還有一個方法 partitioningBy (),分區(qū),不過它的參數(shù)位于是boolean類型。

總結(jié)

以上是生活随笔為你收集整理的stream distinct去重_再来看看Java的新特性——Stream流的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。