Java8 Stream接口流式方法:map操作、filter操作以及flatMap操作
點擊關注公眾號,利用碎片時間學習
關于stream 流式操作,在rt.jar 包里面,ReferencePipeline管道方式操作數據 下面集成所有操作方法,利用這些流,處理大數據的方式,效率提升明顯,并且很多語言都支持這種操作,相當于統一了這種編程方式。
我們先來看看這三個操作過濾的是什么數據,
過濾之后仍然可以循環數據
list.stream().filter(smap?->?null?!=?smap.get("ip")?&&?!"".equals(smap.get("ip"))).forEach(imp?->?{listipzone.add(wry.findIP(imp.get("ip").toString())); });1,filter操作,我們先看方法的定義
源碼如下Stream<T> filter(Predicate<? super T> predicate);一個單純的過濾操作直接返回傳入類型
String[]?dd?=?{?"a",?"b",?"c"?};Stream<String>?stream?=?Arrays.stream(dd);stream.filter(str?->?str.equals("a")).forEach(System.out::println);//返回字符串為a的值2.map操作,先看方法定義
源碼如下 ?<R> Stream<R> map(Function<? super T, ? extends R> mapper);
這個方法傳入一個Function的函數式接口,這個接口,接收一個泛型T,返回泛型R,map函數的定義,返回的流,表示的泛型是R對象,這個表示,調用這個函數后,可以改變返回的類型
public?static?void?main(String[]?args)?{Integer[]?dd?=?{?1,?2,?3?};Stream<Integer>?stream?=?Arrays.stream(dd);stream.map(str?->?Integer.toString(str)).forEach(str?->?{System.out.println(str);//?1?,2?,3System.out.println(str.getClass());//?class?java.lang.String});List<Emp>?list?=?Arrays.asList(new?Emp("a"),?new?Emp("b"),?new?Emp("c"));list.stream().map(emp?->?emp.getName()).forEach(str?->?{System.out.println(str);});}public?static?class?Emp?{private?String?name;public?Emp()?{super();}public?Emp(String?name)?{super();this.name?=?name;}public?String?getName()?{return?name;}public?void?setName(String?name)?{this.name?=?name;}}可以看到,我們把Integer,變成了String輸出,把Emp對象里的name字符串,單獨輸出;現在,我們只看到了一個forEach的終端操作,后面,我們會看到,更多的終端操作,把map操作后,改變的對象類型,返回各種類型的集合,或者對數字類型的,返回求和,最大,最小等的操作;
3.flatMap操作,我們還是先看接口定義
包含前面兩種過濾類型
<R>?Stream<R>?flatMap(Function<??super?T,???extends?Stream<??extends?R>>?mapper);這個接口,跟map一樣,接收一個Fucntion的函數式接口,不同的是,Function接收的泛型參數,第二個參數是一個Stream流;方法,返回的也是泛型R,具體的作用是把兩個流,變成一個流返回,下面,我們看一個案例,來詳細解答,怎么把兩個流的內容,變成一個流的內容
public?static?void?main(String[]?args)?{String[]?strs?=?{?"aaa",?"bbb",?"ccc"?};Arrays.stream(strs).map(str?->?str.split("")).forEach(System.out::println);//?Ljava.lang.String;@53d8d10aArrays.stream(strs).map(str?->?str.split("")).flatMap(Arrays::stream).forEach(System.out::println);//?aaabbbcccArrays.stream(strs).map(str?->?str.split("")).flatMap(str?->?Arrays.stream(str)).forEach(System.out::println);//?aaabbbccc}首先,第二段代碼,才輸出的具體的字符串;
第一段輸出代碼里,我們先看map操作,通過上面對map的介紹,我們可以看到,map可以改變返回的Stream的泛型,str.split(""),根據空字符串分隔,返回的類型是一個數組,返回的流也是Stream<String[]>,而不是Stream<String>;在第二段代碼中,數組的流,經過map操作,返回Stream<String[]>后,再經過flatMap,把數組通過Arrays.stream變成一個新的流,再返回到原來的流里;這樣,兩個流就合并成一個流;第三段代碼,是第二段代碼的,另一種寫法;
PS ?簡單操作示例 ? 1filter 過濾,2 map可以返回其它類型,3 flatMap合并兩個流數據
String[]?includes=new?String[10];includeList.toArray(includes);List<String>?maplist?=??includeList.stream().map(s?->?s.equals("a6")?"a6L":s).collect(Collectors.toList());List<String>?filterlist?=?includeList.stream().filter(s?->?s.equals("a6")).collect(Collectors.toList());includeList.stream().map(s?->?s.equals("a6")?"a6L":s).forEach(System.out::println);//直接操作里面的數據,?改變邏輯后可以返回list等filterlist.forEach(System.out::println);//?只打印a6過濾的數據maplist.forEach(System.out::println);4 ?構造流的幾種常見方法
Stream?stream?=?Stream.of("a",?"b",?"c");//?2.?ArraysString?[]?strArray?=?new?String[]?{"a",?"b",?"c"};stream?=?Stream.of(strArray);stream?=?Arrays.stream(strArray);//?3.?CollectionsList<String>?list?=?Arrays.asList(strArray);stream?=?list.stream();//?map對象進行?排序對比,最主要還是要把數字轉化為?Integer類型去比較,否則只是字符串比較,無意義,封裝成一個可比較的數據類型,轉化字符串為數字類型?就可能排序了model.put("data",?listMap.stream().sorted((a,?b)?->?Integer.valueOf(b.get("count").toString()).compareTo(Integer.valueOf(a.get("count").toString())))5 流轉換為其它數據結構
//?1.?Array String[]?strArray1?=?stream.toArray(String[]::new); //?2.?Collection List<String>?list1?=?stream.collect(Collectors.toList()); List<String>?list2?=?stream.collect(Collectors.toCollection(ArrayList::new)); Set?set1?=?stream.collect(Collectors.toSet()); Stack?stack1?=?stream.collect(Collectors.toCollection(Stack::new)); //?3.?String String?str?=?stream.collect(Collectors.joining()).toString(); //分組構造Map Map<Integer,?String>?factoryMap?=?factoryConfigDOS.stream().collect(?Collectors.groupingBy(AgencyDailySalaryFactoryConfigDO::getFenceId,?Collectors.mapping(AgencyDailySalaryFactoryConfigDO::getFactoryName,?joining(","))?));//Map轉化??函數表達式轉成MAP,key1和key2重復就覆蓋不然會報錯 Map?nameMap?=?incumbentExcelInfoList.stream().collect(Collectors.toMap(info?->?info.getIdCard(),?info?->?info.getName(),(key1,key2)->key2));一個 Stream 只可以使用一次
很多API都有這種方式的操作,對后期大數據或者其它語言兼容,解決跨語言的問題,也提交了效率,日后要以這種方式處理數據,
6 流的操作
接下來,當把一個數據結構包裝成 Stream 后,就要開始對里面的元素進行各類操作了。常見的操作可以歸類如下。
Intermediate:??(中間) map?(mapToInt,?flatMap?等)、?filter、?distinct、?sorted、?peek、?limit、?skip、?parallel、?sequential、?unorderedTerminal:(終端) forEach、?forEachOrdered、?toArray、?reduce、?collect、?min、?max、?count、?anyMatch、?allMatch、?noneMatch、?findFirst、?findAny、?iteratorShort-circuiting:(短路) anyMatch、?allMatch、?noneMatch、?findFirst、?findAny、?limilimit/skip
limit 返回 Stream 的前面 n 個元素;skip 則是扔掉前 n 個元素(它是由一個叫 subStream 的方法改名而來)。
List<String>?personList2?=?persons.stream(). map(Person::getName).limit(10).skip(3).collect(Collectors.toList());System.out.println(personList2);所有 Stream 的操作必須以 lambda 表達式為參數
merge為Map接口新增的默認方法
//?k-8值存在為value8->執行merge函數->直接返回"NewMerge8"->newValue為"NewMerge8" //?執行put->所以這里輸出"NewMerge8" map.merge(8,?"merge",?(value,?newValue)?->?"NewMerge8"); System.out.println(map.get(8));//?合并方式 String?newValue2?=?map.merge(9,?"concat",?(value,?newValue)?->?value.concat(newValue));//?解釋:從字符串序列中過濾出以字符a開頭的字符串并迭代打印輸出 stringList.stream().filter((s)?->?s.startsWith("a")).forEach(System.out::println);組合查詢 ?主要是peek 監視消費后執行的動作
List<Integer>?nums?=?Lists.newArrayList(1,1,null,2,3,4,null,5,6,7,8,9,10); System.out.println(“sum?is:”+nums.stream().filter(num?->?num?!=?null).distinct().mapToInt(num?->?num?*?2).peek(System.out::println).skip(2).limit(4).sum());Integer類型的List,獲取其對應的Stream對象,然后進行過濾掉null,再去重,再每個元素乘以2,再每個元素被消費的時候打印自身,在跳過前兩個元素,最后去前四個元素進行加和運算
7 數據并行化操作
Stream 的并行化也是 Java 8 的一大亮點。數據并行化是指將數據分成塊,為每塊數據分配單獨的處理單元。這樣可以充分利用多核 CPU 的優勢。
并行化操作流只需改變一個方法調用。如果已經有一個 Stream 對象,調用它的 parallel()方法就能讓其擁有并行操作的能力。如果想從一個集合類創建一個流,調用 parallelStream() 就能立即獲得一個擁有并行能力的流。
int?sumSize?=?Stream.of("Apple",?"Banana",?"Orange",?"Pear")?.parallel()?.map(s?->?s.length())?.reduce(Integer::sum)?.get();?assertEquals(sumSize,?21);詳情API參考
https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/
來源:blog.csdn.net/limingcai168/article/details/85265089
推薦:
主流Java進階技術(學習資料分享)
PS:因為公眾號平臺更改了推送規則,如果不想錯過內容,記得讀完點一下“在看”,加個“星標”,這樣每次新文章推送才會第一時間出現在你的訂閱列表里。點“在看”支持我們吧!
總結
以上是生活随笔為你收集整理的Java8 Stream接口流式方法:map操作、filter操作以及flatMap操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHP实现小偷程序
- 下一篇: 第八篇 :微信公众平台开发实战Java版