stream distinct去重_再来看看Java的新特性——Stream流
為什么要使用流?
摘要中已經說明了,為了提高開發效率。流可以幫助我們高效操作集合,流幫助我們通過流水線的方式對集合進行刪減、合并、排序、修改,并最終返回我們想要的元素數據或統計數據。流水線的意思是說,一批元素不需要等待全部元素都完成某步操作,才進行下步操作,而是可以盡早進行下步操作,就好像流水線工廠一樣,這為流高效運作提供了基礎。流還有一個內部迭代的概念,就是把for循環顯示迭代隱藏起來了,這樣可以更方便的并行開發。
流的使用
準備
在使用流之前需要做些準備,首先說明兩個概念:中間操作 和 終端操作。中間操作就好比生產車間的一步一步元素處理,每步處理之后,里面的元素樣式或者數據結構可能發生改變了,但是它還是流。終端操作就好比產品生產完了,要打包裝箱,變成最終消費者可見的最終形態,此時,它已經是產品,不再是流了。
接著為了演示操作,先模擬幾條數據
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應該是Stream操作里面最常見的了,過濾器顧名思義就是過濾數據用的,filter的參數可以是lambda表達式。
//比如下面這句話,就是得到所有價格小于10的食物,得到的還是流。 //stream()方法將集合轉成流 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()//經過去重,流還剩1、2、3.skip(1)//跳過第一個元素,流中還有2、3.limit(1);//截取第一個元素,流中還剩2map
map映射,上面的filter是將元素篩選,map則是改變元素的樣式。比如,我們想要知道所有小于10塊食物的名字。
menu.stream().filter(jsonObject -> jsonObject.getInt("price")<10)//此時還是jsonObject.map(jsonObject -> jsonObject.getStr("name"));//此時變成了StringflatMap
流的合并,可以將多個數組合并操作,這樣返回元素不是流,而是具體元素本身了。
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);上面個方法返回的都是boolean類型,findFirst、findAny返回的都是元素。
//關于Optional,先不關心,總之是元素就對了 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":"宮保雞丁"}以上兩個方法,只要找到符合條件的數據,流就提前結束了。為什么都是輸出第一個元素,卻要實現有兩個方法呢?因為并行,findAny在并行方面限制會少一些。
reduce
最開始的時候說了,最終的返回值可以是元素集合,也可以是統計數據(或者說歸納),比如說元素求和。假設我們需要menu中所有食品各要一份需要花多少錢。
Optional<Integer> price = menu.stream()//List<JsonObject>.map(jsonObject -> jsonObject.getInt("price"))//先將元素轉成數字List<Integer>.reduce((x, y) -> x + y); System.out.println(price.get());max和min
這個好理解,就是最大值和最小值嘛。效果類似于
.reduce(Integer::max) .reduce(Integer::min)常用流匯總
其中沒有展示sorted、count這個都好理解。至于collect這個后面講,用的比較多。
流的轉化
除了對象流(Stream)以外,還有一些類型流,比如說 IntStream(以 IntStream 舉例,其他類似)上面求和返回的是Optional對象,那可以直接返回Integer類型嗎?
//使用映射方法mapToInt()就ok了 int price = menu.stream()//Stream.mapToInt(jsonObject -> jsonObject.getInt("price"))//IntStream.sum(); //類型流轉化回對象流,可以使用boxed() IntStream intStream = menu.stream().mapToInt(jsonObject -> jsonObject.getInt("price")); Stream<Integer> boxed = intStream.boxed(); //當然了IntStream中有很多int類型操作的方法,就不一一舉例了,源碼打開一看,見名知意收集器
前面講的常用的中間操作,返回值都是流,還有一些中斷操作,返回值都是Optional或者數值。可別忘了Stream最開始的初衷是為了解決集合操作問題。最終轉化成集合使用的中斷操作collect,參數是接口 Collector,里面有眾多轉化方法。
轉換成集合
最常用的莫非toList() 這個方法了,將返回結果變成List。
List<JSONObject> list = menu.stream().filter(jsonObject -> jsonObject.getInt("price") < 10).collect(Collectors.toList()); //當然還有toSet()等等,觸類旁通字符串拼接
比較常用,就是字符串鏈接了。使用joining()方法
String s = menu.stream().filter(jsonObject -> jsonObject.getInt("price") < 10).map(jsonObject -> jsonObject.getStr("name")).collect(Collectors.joining(","));分組
根據提供的屬性分組,使用 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 (),分區,不過它的參數位于是boolean類型。
總結
以上是生活随笔為你收集整理的stream distinct去重_再来看看Java的新特性——Stream流的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一般性网络错误 请检查网络文档_如何编写
- 下一篇: 程序语言python循环_《python