11-stream流-流水线编码、filter等中间方法、forEach等终止方法、collect获取返回结果方法、lambda练习
文章目錄
- 1、體驗Stream流【理解】
- 2、Stream流的常見生成方式【應用】
- 代碼1:單列集合流
- 代碼2:雙列集合流
- 代碼3:數組—》流
- 代碼4:同種數據類型的多個數據
- Stream流的獲取小結
- 3、Stream流中間操作方法【應用】
- filter代碼演示
- limit&skip代碼演示
- concat&distinct代碼演示
- 4、Stream流終結操作方法【應用】
- forEach
- count() 返回此流中的元素數
- 在Stream流中無法直接修改集合、數組等數據源中的數據(無法直接修改那塊內存)
- 5、Stream流的收集操作【應用】
- 收集到List和Set 單列集合中
- 收集到Map 雙列集合中
- 6、Stream流綜合練習【應用】★
1、體驗Stream流【理解】
-
案例需求
按照下面的要求完成集合的創建和遍歷
- 創建一個集合,存儲多個字符串元素
- 把集合中所有以"云"開頭的元素存儲到一個新的集合
- 再把"云"開頭的集合中的長度為3的元素存儲到一個新的集合
- 遍歷上一步得到的集合
-
原始方式示例代碼
- 使用Stream流示例代碼(三行就實現了復雜邏輯)
-
Stream流的好處
- 直接閱讀代碼的字面意思即可完美展示無關邏輯方式的語義:獲取流、過濾姓張、過濾長度為
-
逐一打印
- Stream流把真正的函數式編程風格引入到Java中
- 代碼簡潔
2、Stream流的常見生成方式【應用】
- Stream流的思想
-
Stream流的三類方法
- 獲取Stream流
- 創建一條流水線,并把數據放到流水線上準備進行操作
- 中間方法
- 流水線上的操作
- 一次操作完畢之后,還可以繼續進行其他操作
- 終結方法
- 一個Stream流只能有一個終結方法
- 是流水線上的最后一個操作
- 獲取Stream流
-
生成Stream流的方式
-
Collection體系集合
使用默認方法stream()生成流, default Stream< E> stream()
-
Map體系集合
把Map轉成Set集合(keySet或entrySet),間接的生成流
-
數組
通過Arrays中的靜態方法stream生成流
-
同種數據類型的多個數據
通過Stream接口的靜態方法of(T… values)生成流
-
-
代碼演示
代碼1:單列集合流
獲取stream流: Stream< String> stream = list.stream();
操作stream流: stream.forEach(s -> System.out.print(s+" "));
代碼2:雙列集合流
先獲取keySet或者entrySet,再獲取流
map.keySet().stream() 或者 map.entrySet().stream()
代碼3:數組—》流
public static void main(String[] args) {//數組-》流int[] arr={1,2,3,4,5};Arrays.stream(arr).forEach(s->System.out.print(s+" "));//"1 2 3 4 5"//拓展System.out.println();System.out.println(Arrays.toString(arr));//數組輸出System.out.println(Arrays.stream(arr).max().getAsInt());//流求 數組最大值 5System.out.println(Arrays.stream(arr).min().getAsInt());//流求 數組最小值 1System.out.println(Arrays.stream(arr).average().getAsDouble());//流求 數組平均 3.0System.out.println(Arrays.stream(arr).count());//流求 數組長度 5System.out.println(Arrays.stream(arr).sum());//流求 數組求和 15}代碼4:同種數據類型的多個數據
public static void main(String[] args) {//同種數據類型多個數據->流水線Stream.of(1,4,6,7,8,2,3,5,10,9).forEach(s->System.out.print(s+" "));System.out.println();//DIY應用 過濾掉奇數Stream.of(1,4,6,7,8,2,3,5,10,9).filter(i->i%2!=0).forEach(i->System.out.print(i+" "));}Stream流的獲取小結
單列集合 : 集合對象.stream();雙列集合 : 不能直接獲取,需要間接獲取集合對象.keySet().stream();集合對象.entrySet().stream();數組 :Arrays.stream(數組名);同種數據類型的多個數據:Stream.of(數據1,數據2,數據3......);3、Stream流中間操作方法【應用】
-
概念
中間操作的意思是,執行完此方法之后,Stream流依然可以繼續執行其他操作
-
常見方法
方法名說明 Stream< T> filter(Predicate predicate) 用于對流中的數據進行過濾 Stream< T> limit(long maxSize) 返回此流中的元素組成的流,截取前指定參數個數的數據 Stream< T> skip(long n) 跳過前指定參數個數的數據,返回由該流的剩余元素組成的流 static < T> Stream< T> concat(Stream a, Stream b) 合并a和b兩個流為一個流 Stream< T> distinct() 返回由該流的不同元素(根據hashCode和equals方法 )組成的流
filter代碼演示
public static void main(String[] args) {ArrayList<String> list1=new ArrayList<>();initList(list1);System.out.println(list1);//留下"云"開頭的 過濾掉其他的//filter方法獲取流中的每個數據//而test方法中的s,就依次表示流中的每一個數據//則只需在test方法中s進行判斷就行了:true該數據留校 false該數據丟棄System.out.println("==============匿名內部類=============");list1.stream().filter(new Predicate<String>() {@Overridepublic boolean test(String s) {return s.startsWith("云");}}).forEach(s->System.out.print(s+" "));System.out.println("\n==============lambda表達式=============");//因為Predicate接口中只有一個★抽象方法Test★,因此可以用lambda表達式簡化//接下來,再用lambda表達式簡化一下就ok了list1.stream().filter((String s)->{return s.startsWith("云");}).forEach(s->System.out.print(s+" "));System.out.println("\n==============lambda表達式省略寫法=============");//參數只有一個: 可以省略 類型與括號()//方法體語句只有一條: return可以省略 ";"可以省略list1.stream().filter(s->s.startsWith("云")).forEach(s->System.out.print(s+" "));}public static void initList(ArrayList<String> list){String[] ss={"云天河","韓菱紗","慕容紫英","柳夢璃","玄霄","夙玉","云天青","云來石","云叔"};for (String s : ss) list.add(s);}limit&skip代碼演示
Stream< T> limit(long maxSize); || eg:limit(3) 截取前3個數據 Stream< T>
Stream< T> skip(long n) || eg:skip(3) 前3個數據不要(剩余的都留下)
concat&distinct代碼演示
static < T> Stream< T> concat(Stream a, Stream b) | 合并a和b兩個流為一個流
Stream< T> distinct() 流中數據去重(根據hashCode和equals方法 )
4、Stream流終結操作方法【應用】
-
概念(★)
終結操作的意思是,執行完此方法之后,Stream流將不能再執行其他操作
-
常見方法
方法名說明 void forEach(Consumer action) 對此流的每個元素執行操作 long count() 返回此流中的元素數
forEach
public static void main(String[] args) {ArrayList<String> list1=new ArrayList<>();initList(list1);System.out.println(list1);//終結方法1:forEach 【終結方法執行后,本次流水線結束。不能再操作此流水線了】System.out.println("=============forEach:匿名內部類============");//在forEach方法的底層,會循環獲取到流中的每一個數據.//并循環調用accept方法,并把每一個數據傳遞給accept方法//s就依次表示了流中的每一個數據.//所以,我們只要在accept方法中,寫上處理的業務邏輯就可以了.list1.stream().forEach(new Consumer<String>() {@Overridepublic void accept(String s) {System.out.print(s+" ");}});//Consumer接口內只有一個抽象方法,可以用lambda表達式System.out.println("\n=============forEach:lambda表達式============");list1.stream().forEach((String s)->{System.out.print(s+" ");});//一個參數:省略 類型+小括號//一條語句:省略 return、分號、大括號System.out.println("\n=============forEach:lambda表達式簡化============");list1.stream().forEach(s->System.out.print(s+" "));}public static void initList(ArrayList<String> list){String[] ss={"云天河","韓菱紗","慕容紫英","柳夢璃","玄霄","夙玉","云天青","云來石","云叔"};for (String s : ss) list.add(s);}count() 返回此流中的元素數
public static void main(String[] args) {ArrayList<String> list1=new ArrayList<>();initList(list1);System.out.println(list1);//終結方法2:count(): 統計流中元素個數【終結方法執行后,本次流水線結束。不能再操作此流水線了】long count = list1.stream().count();System.out.println(count);//9}public static void initList(ArrayList<String> list){String[] ss={"云天河","韓菱紗","慕容紫英","柳夢璃","玄霄","夙玉","云天青","云來石","云叔"};for (String s : ss) list.add(s);}在Stream流中無法直接修改集合、數組等數據源中的數據(無法直接修改那塊內存)
Stream流的收集方法
練習:
定義一個集合,并添加一些整數1,2,3,4,5,6,7,8,9,10
將集合中的奇數刪除,只保留偶數。
遍歷集合得到2,4,6,8,10。
5、Stream流的收集操作【應用】
stream流無法直接修改集合中元素,有修改需求時咋辦呢?有專門的收集API
-
概念
對數據使用Stream流的方式操作完畢后,可以把流中的數據收集到集合中
-
常用方法(collect也是終結方法)
方法名說明 R collect(Collector collector) 把結果收集到集合中 -
工具類Collectors提供了具體的收集方式
方法名說明 public static Collector toList() 把元素收集到List集合中 public static Collector toSet() 把元素收集到Set集合中 public static Collector toMap(Function keyMapper,Function valueMapper) 把元素收集到Map集合中
收集到List和Set 單列集合中
案例: 只保留list集合中的偶數(刪除所有奇數)
public static void main(String[] args) {ArrayList<Integer> list1=new ArrayList<>();for (int i = 1; i <= 10; i++) list1.add(i);//快捷寫法: 10.forilist1.add(10);list1.add(10);list1.add(10);list1.add(10);list1.add(10);//1.收集到list中//filter負責過濾數據的.//collect負責收集數據.//獲取流中剩余的數據,但是他不負責創建容器,也不負責把數據添加到容器中.//Collectors.toList() : 在底層會創建一個List集合.并把所有的數據添加到List集合中.List<Integer> list = list1.stream().filter(i -> i % 2 == 0).collect(Collectors.toList());System.out.println(list);//[2, 4, 6, 8, 10, 10, 10, 10, 10, 10]//2.收集到Set中Set<Integer> set = list1.stream().filter(i -> i % 2 == 0).collect(Collectors.toSet());System.out.println(set);[2, 4, 6, 8]}收集到Map 雙列集合中
案例:
6、Stream流綜合練習【應用】★
-
案例需求
現在有兩個ArrayList集合,分別存儲6名男演員名稱和6名女演員名稱,要求完成如下的操作
- 男演員只要名字為3個字的前三人
- 女演員只要姓楊的,并且不要第一個
- 把過濾后的男演員姓名和女演員姓名合并到一起
- 把上一步操作后的元素作為構造方法的參數創建演員對象,遍歷數據
演員類Actor已經提供,里面有一個成員變量,一個帶參構造方法,以及成員變量對應的get/set方法
-
代碼實現
演員類
public class Actor {private String name;//全參、空參、get/set、toString }測試類:
public static void main(String[] args) {ArrayList<String> manList = new ArrayList<>();manList.add("張國立"); manList.add("張晉"); manList.add("劉燁");manList.add("鄭伊健"); manList.add("徐崢"); manList.add("王寶強");ArrayList<String> womanList = new ArrayList<>();womanList.add("劉亦菲"); womanList.add("楊紫"); womanList.add("關曉彤");womanList.add("張天愛"); womanList.add("楊冪"); womanList.add("趙麗穎");//男演員只要名字為3個字的前兩人Stream<String> stream1 = manList.stream().filter(s -> s.length() == 3).limit(2);//女演員只要姓林的,并且不要第一個Stream<String> stream2 = womanList.stream().filter(s -> s.startsWith("楊")).skip(1);//合并 后封裝從對象再打印出對象Stream.concat(stream1,stream2).forEach(s -> {Actor actor = new Actor(s);System.out.println(actor);});}總結
以上是生活随笔為你收集整理的11-stream流-流水线编码、filter等中间方法、forEach等终止方法、collect获取返回结果方法、lambda练习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue基础学习
- 下一篇: bga封装扇出过孔,用Allegro软件