Java 8 Streams的簡單使用方法


Java 8 Streams的簡單使用方法

 1 package JDK8Test;
 2 import java.util.ArrayList;
 3 
 4 public class Main 
 5 {
 6     public static void main(String[] args) 
 7     {
 8         ArrayList<Integer> nums=new ArrayList<Integer>();
 9         nums.add(1);
10         nums.add(null);
11         nums.add(3);
12         nums.add(4);
13         nums.add(null);
14         nums.add(6);
15         int n=(int)nums.stream().filter(num->num!=null).count();
16         System.out.println(n);//4
17     }
18 }

  上面這段代碼是獲取一個List中,元素不為null的個數。

  

  

  紅色框中的語句是一個Stream的生命開始的地方,負責創建一個Stream實例;綠色框中的語句是賦予Stream靈魂的地方,把一個Stream轉換成另外一個Stream,紅框的語句生成的是一個包含所有nums變量的Stream,通過綠框的filter方法以后,重新生成了一個過濾掉原nums列表所有null以后的Stream;藍色框中的語句是豐收的地方,把Stream的里面包含的內容按照某種算法來匯聚成一個值。  

  使用Stream的基本步驟:

  1.創建Stream;

  2.轉換Stream,每次轉換原有Stream對象不改變,返回一個新的Stream對象(可以有多次轉換);

  3.對Stream進行聚合操作,獲取想要的結果;

  怎么得到Stream:

  ①使用Stream靜態方法來創建Stream:

  of方法:有兩個重載方法,一個接受變長參數,一個接受單一值 
  Stream integerStream = Stream.of(1, 2, 3, 5);
  Stream stringStream = Stream.of(“taobao”);

  ②通過Collection接口的默認方法stream(),把一個Collection對象轉換成Stream。

  轉換Stream:

  轉換Stream其實就是把一個Stream通過某些行為轉換成一個新的Stream。

  ①distinct: 對於Stream中包含的元素進行去重操作(去重邏輯依賴元素的equals方法),新生成的Stream中沒有重復的元素;

  ②filter: 對於Stream中包含的元素使用給定的過濾函數進行過濾操作,新生成的Stream只包含符合條件的元素;

  

  

  ③map: 對於Stream中包含的元素使用給定的轉換函數進行轉換操作,新生成的Stream只包含轉換生成的元素。這個方法有三個對於原始類型的變種方法,分別是:mapToInt,mapToLong和mapToDouble。這三個方法也比較好理解,比如mapToInt就是把原始Stream轉換成一個新的Stream,這個新生成的Stream中的元素都是int類型。
  

  例子:

 1 package JDK8Test;
 2 import java.util.*;
 3 import java.util.Arrays;
 4 import java.util.stream.Collectors;
 5 
 6 public class Main 
 7 {
 8     public static void main(String[] args) 
 9     {
10         List<String> list=Arrays.asList(new String[] {"Ni","Hao","Lambda"});
11         List<String> list2=list.stream().map(item->item.toLowerCase()).collect(Collectors.toList());
12         System.out.println(list2);
13     }//[ni, hao, lambda]
14 }    

  這段代碼就是對一個字符串的列表,把其中包含的每個字符串都轉換成全小寫的字符串。注意代碼第四行的map方法調用,這里map方法就是接受了一個lambda表達式。

 1 package JDK8Test;
 2 import java.util.*;
 3 import java.util.Arrays;
 4 import java.util.stream.Collectors;
 5 
 6 public class Main 
 7 {
 8     public static void main(String[] args) 
 9     {
10         List<String> list=Arrays.asList(new String[] {"Ni","Hao","Lambda"});
11         List<String> list2=list.stream().map(item->{return "lambda:"+item;}).collect(Collectors.toList());
12         list2.forEach(System.out::println);
13     }
14 }
15 /*
16 lambda:Ni
17 lambda:Hao
18 lambda:Lambda
19 */

  集合的forEach()方法,對集合進行遍歷,小括號中的方法就是應用到集合中每個元素的身上,以達到遍歷的目的。

 1 package JDK8Test;
 2 import java.util.*;
 3 import java.util.Arrays;
 4 import java.util.stream.Collectors;
 5 
 6 public class Main 
 7 {
 8     public static void main(String[] args) 
 9     {
10         String waibu="lambda:";
11         List<String> proStrs=Arrays.asList(new String[] {"Ni","Hao","Lambda"});
12         List<String> exeStrs=proStrs.stream().map(chuandi->{
13             long zidingyi=System.currentTimeMillis();
14             return waibu+chuandi+"------:"+zidingyi;
15         }).collect(Collectors.toList());
16         exeStrs.forEach(System.out::println);
17     }
18 }
19 /*
20 lambda:Ni------:1559118070052
21 lambda:Hao------:1559118070052
22 lambda:Lambda------:1559118070052
23 */

  

  lambda表達式可以訪問給它傳遞的變量,訪問自己內部定義的變量,同時也能訪問它外部的變量。 不過lambda表達式訪問外部變量有一個非常重要的限制:變量不可變(只是引用不可變,而不是真正的不可變)。 當在表達式內部修改waibu = waibu + " ";時,IDE就會報錯。因為變量waibu被lambda表達式引用,所以編譯器會隱式的把其當成final來處理。
  以前Java的匿名內部類在訪問外部變量的時候,外部變量必須用final修飾。現在java8對這個限制做了優化,可以不用顯示使用final修飾,但是編譯器隱式當成final來處理。

  ④peek: 生成一個包含原Stream的所有元素的新Stream,同時會提供一個消費函數(Consumer實例),新Stream每個元素被消費的時候都會執行給定的消費函數;

  

  ⑤limit: 對一個Stream進行截斷操作,獲取其前N個元素,如果原Stream中包含的元素個數小於N,那就獲取其所有的元素;

  

  ⑥skip: 返回一個丟棄原Stream的前N個元素后剩下元素組成的新Stream,如果原Stream中包含的元素個數小於N,那么返回空Stream;

  

  匯聚Stream:

  

  匯聚操作(也稱為折疊)接受一個元素序列為輸入,反復使用某個合並操作,把序列中的元素合並成一個匯總的結果。比如查找一個數字列表的總和或者最大值,或者把這些數字累積成一個List對象。Stream接口有一些通用的匯聚操作,比如reduce()和collect();也有一些特定用途的匯聚操作,比如sum(),max()和count()。注意:sum方法不是所有的Stream對象都有的,只有IntStream、LongStream和DoubleStream實例才有。

  ①reduce():把 Stream 元素組合起來。它提供一個起始值(種子),然后依照運算規則(BinaryOperator),返回單個的結果值,並且reduce操作每處理一個元素總是創建一個新值。

  

  ②collect:正如其名字顯示的,它可以把Stream中的所有元素收集到一個結果容器中(比如Collection)。

  Java 8還給我們提供了Collector的工具類——Collectors,其中已經定義了一些靜態工廠方法,比如Collectors.toCollection()收集到Collection中, Collectors.toList()收集到List中和Collectors.toSet()收集到Set中。
  List numsWithoutNull = nums.stream().filter(num -> num != null).collect(Collectors.toList());

  ③count方法:獲取Stream中元素的個數。

  – 搜索相關
  – allMatch:是不是Stream中的所有元素都滿足給定的匹配條件
  – anyMatch:Stream中是否存在任何一個元素滿足匹配條件
  – findFirst: 返回Stream中的第一個元素,如果Stream為空,返回空Optional
  – noneMatch:是不是Stream中的所有元素都不滿足給定的匹配條件
  – max和min:使用給定的比較器(Operator),返回Stream中的最大|最小值
  下面給出allMatch和max的例子:

 1 package JDK8Test;
 2 import java.util.*;
 3 
 4 
 5 public class Main 
 6 {
 7     public static void main(String[] args) 
 8     {
 9         ArrayList<Integer> nums=new ArrayList<Integer>();
10         nums.add(1);
11         nums.add(null);
12         nums.add(3);
13         nums.add(4);
14         nums.add(null);
15         nums.add(6);
16         System.out.println(nums.stream().filter(item->item!=null).allMatch(item->item<100));
17     }
18 }
19 /*
20 true
21 */

  以上代碼,判斷nums列表里的不為null元素是否都滿足“小於100“這個條件,輸出為true。

 1 package JDK8Test;
 2 import java.util.*;
 3 
 4 
 5 public class Main 
 6 {
 7     public static void main(String[] args) 
 8     {
 9         ArrayList<Integer> nums=new ArrayList<Integer>();
10         nums.add(1);
11         nums.add(null);
12         nums.add(3);
13         nums.add(4);
14         nums.add(null);
15         nums.add(6);
16         nums.stream().filter(item->item!=null).max((o1,o2)->o1-o2).ifPresent(System.out::println);
17     }
18 }
19 /*
20 6
21 */

  以上代碼,先把nums里為null的元素過濾掉,然后輸出nums里元素的最大值。輸出為6。

 

 

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM