第三章 Stream API,第三章streamapi

來源:互聯網
上載者:User

第三章 Stream API,第三章streamapi

引例:

1         List<String> strList = Arrays.asList("zhaojigang","nana","tianya","nana");2         Stream<String> streamList = strList.stream();//集合轉為stream3         strList = streamList.distinct().filter(str->!str.equals("tianya")).sorted(String::compareTo).collect(Collectors.toList());4         strList.forEach(System.out::println);

說明:

  • 第一行:建立數組並轉為List
  • 第二行:根據List建立stream
  • 第三行:對該stream進行去重-->選擇-->排序-->stream轉為List
  • 第四行:遍曆該List

以上代碼顯示了stream API的方便。當然,上邊的代碼可以更為簡潔,如下改為一行:

Arrays.asList("zhaojigang","nana","tianya","nana").stream().distinct().filter(str->!str.equals("tianya")).sorted(String::compareTo).collect(Collectors.toList()).forEach(System.out::println);

以上代碼有一個易錯點:filter是選擇而不是過濾,即filter是選擇滿足條件的元素

一、建立Stream

三種常用API:

  • 集合-->Stream:stream()
  • 數組-->Stream:Stream.of(T t)或者Arrays.stream(T[] t)
  • 任意元素-->Stream:Stream.of(T... values)
 1         List<String> strList = Arrays.asList("zhaojigang","nana","tianya","nana"); 2         Stream<String> streamList = strList.stream();//集合轉為stream 3          4         String[] strArray = {"java","c++","c"}; 5         Stream<String> streamArray = Stream.of(strArray);//數組轉為Stream 6         Stream<String> streamArray2 = Arrays.stream(strArray);//數組轉為Stream 7          8         Stream<String> streamPartArray = Arrays.stream(strArray, 0, 2);//轉換部分數組,範圍:[0,2) 9         10         Stream<String> streamSelf = Stream.of("python","basic","php");//任意元素

還有一種:用於產生無限流的,Stream.generate(Supplier<T> s)。

 

二、Stream 2 array/collection/String/map

1、stream2array

1         Stream<String> strStream = Stream.of("java","c++","c","python");2         Object[] objectArray = strStream.toArray();//只能返回Object[]3         String[] strArray = strStream.toArray(String[]::new);//構造器引用(類似於方法引用),可以返回String[]

說明:

通過構造器引用(類似於方法引用),可以構造出具體類型的數組。

 

2、stream2collection

1         List<String> strList = strStream.collect(Collectors.toList());//返回List2         Set<String> strSet = strStream.collect(Collectors.toSet());//返回set3         ArrayList<String> strArrayList = strStream.collect(Collectors.toCollection(ArrayList::new));//收集到指定的List集合,例如收集到ArrayList

說明:

通過構造器引用,可以構造出具體類型的集合。

 

3、將stream中的元素拼接起來(joining()、joining(","))

1         Stream<String> strStream = Stream.of("java","c++","c","python");2         String str = strStream.collect(Collectors.joining());//將所有字串拼接起來,結果:javac++cpython3         System.out.println(str);4         5         String str2 = strStream.collect(Collectors.joining(","));//將所有字串拼接起來,中間用","隔開,結果:java,c++,c,python6         System.out.println(str2);

 

4、stream2map(toMap、toConcurrentMap)

 1         Stream<String> strStream = Stream.of("java","c++","c","python"); 2         Map<String, Integer> map1 = strStream.collect(Collectors.toMap(Function.identity(), (x)->0)); 3         //Function.identity()-->返回strStream中的元素,toMap方法的我兩個參數都是Function介面型的,所以第二個參數即使只放0,也不能直接寫作0,可以使用如上的方式進行操作 4          5         for(String key : map1.keySet()){ 6             System.out.println("key:"+key+"->"+"value:"+map1.get(key)); 7         } 8         //結果 9         /*10         key:python->value:011         key:c++->value:012         key:c->value:013         key:java->value:014          */

說明:

  • toMap-->stream轉為map
  • Function.identity()-->返回stream中的元素

如果key重複的話,這時就會出現問題"duplicate key",採用如下方式解決(增加第三個參數):

1         Stream<String> strStream = Stream.of("java","c++","c","python","java");2         Map<String, Integer> map1 = strStream.collect(Collectors.toMap(Function.identity(), //key3                                                                         (x)->0,             //value4                                                                         (existingValue, newValue) -> existingValue));//如果key重複,取舊值

需要指定返回map的具體類型(增加第四個參數)。

1         Map<String, Integer> map1 = strStream.collect(Collectors.toMap(Function.identity(), //key2                                                                         (x)->0,             //value3                                                                         (existingValue, newValue) -> existingValue,//如果key重複,取舊值4                                                                         TreeMap::new));//返回TreeMap

注意:每一個toMap就會對應一個相應的toConcurrentMap

三、filter(Predicate p)

注意:是選擇而非過濾

1         Stream<String> streamSelf = Stream.of("python","basic","php");2         streamSelf.filter(str->str.startsWith("p")).forEach(System.out::println);

注意:

  • stream也是可以foreach的,沒必要一定要轉化成集合再foreach

更好的寫法可能是下邊這種:

1         Predicate<String> startCondition = str->str.startsWith("p");2         streamSelf.filter(startCondition).forEach(System.out::println);

說明:將條件(通常是lambda運算式)抽取出來。這種方式在多個條件的情況下比較清晰。

注意:函數式介面 = lambda運算式 (即lambda運算式只能返回為函數式介面)

 

四、map(Function mapper)

作用:對流中的每一個元素進行操作。

1         Stream<String> streamSelf = Stream.of("python","basic","php");2         streamSelf.map(String::toUpperCase).forEach(System.out::println);

說明:將流內的每一個String全部轉換為了大寫。

 

五、reduce 

作用:對stream中的每一個元素做彙總操作。

1         Stream<Integer> reduceStream = Stream.of(1,2,3,4,5);2         Optional<Integer> sumOption = reduceStream.reduce((x,y)->x+y);//計算1+2+3+4+5,即對元素中的元素進行彙總計算,而map是對元素中的每一個元素分別計算(注意:如果stream為null的話,就會產生無效的結果,需要使用Optional接收)3         //Optional<Integer> sumOption = reduceStream.reduce(Integer::sum);//計算1+2+3+4+5,即對元素中的元素進行彙總計算,而map是對元素中的每一個元素分別計算4 5         Integer result = reduceStream.reduce(0, Integer::sum);//0為標識值,即計算:0+1+2+。。+5,如果整個stream為null,就返回標識值。6         System.out.println(result);

注意:以上是reduce的簡單形式,即內嵌函式是(T,T)->T,即傳回值和參數類型是一樣的,傳回值和參數類型不同的情境需要自己編寫函數(用的較少)

 

六、Optional

兩種用法:

  • ifPresent(xxx):存在的就執行xxx,不存在就什麼都不執行
  • orElse(xxx):存在就返回存在的值,不存在就返回xxx(可以理解為是預設值)
1         Stream<String> optionalStream = Stream.of("java","python","basic");2         Optional<String> optionValue = optionalStream.filter(str->str.startsWith("p")).findFirst();3         optionValue.ifPresent(str->System.out.println(str));//if optionalValue為true,即str存在,則輸出str,當然也可以使用如下4         String str = optionValue.orElse("xxx");//如果optionValue為false,即不存在以p開頭的字串時,使用"xxx"來替代5         System.out.println(str);

 

 

七、limit skip contact

1、limit(long size)

作用:截取stream的前size個元素。

1         Stream<String> streamSelf = Stream.of("python","basic","php");2         streamSelf.limit(2).forEach(System.out::println);//截取前兩個

2、skip(long size)

作用:跳過stream的錢size個元素

1         Stream<String> streamSelf = Stream.of("python","basic","php");2         streamSelf.skip(2).forEach(System.out::println);//跳過前兩個

3、contact(Stream<T>,Stream<T>)

作用:拼接兩個stream

1         Stream<String> streamSelf = Stream.of("python","basic","php");2         Stream<String> streamSelf2 = Stream.of("python2","basic2","php2");3         Stream.concat(streamSelf, streamSelf2).forEach(System.out::println);

 

八、彙總函式 count max min findFirst findAny anyMatch allMatch noneMatch

1         Stream<String> streamSelf = Stream.of("python","basic","php","b");2         System.out.println(streamSelf.count());//計算流中的元素個數3         Optional<String> largest = streamSelf.max(String::compareToIgnoreCase);//尋找最大值4         if(largest.isPresent()){5             System.out.println(largest.get());6         }

說明:min函數也一樣。

注意:Optional的使用,上邊的是最差的一種形式,見"六"。

 1         Optional<String> firstMatch = streamSelf.filter(str->str.startsWith("b")).findFirst();//尋找第一個合格元素 2         firstMatch.ifPresent(System.out::println);//這是Optional的第一種用法 3          4         Optional<String> anyMatch = streamSelf.parallel().filter(str->str.startsWith("b")).findAny();//返回集合中合格任意一個元素,對於平行處理非常好(因為多個線程只要有一個線程找到了,整個計算就會結束) 5         if(anyMatch.isPresent()){ 6             System.out.println(anyMatch.get());//這裡的結果可能是b,有可能是basic 7         } 8          9         boolean isAnyMatch = streamSelf.parallel().anyMatch(str->str.startsWith("c"));//集合中是否有一個滿足條件10         System.out.println(isAnyMatch);11         12         Stream<String> streamSelf3 = Stream.of("basic","b");13         boolean isAllMatch = streamSelf3.parallel().allMatch(str->str.startsWith("b"));//集合中是否所有元素都滿足條件14         System.out.println(isAllMatch);15         16         boolean isAllNotMatch = streamSelf.parallel().noneMatch(str->str.startsWith("p"));//集合中是否沒有一個元素滿足條件17         System.out.println(isAllNotMatch);

注意:

  • optional的最佳用法:ifPresent()-->如果有就輸出,如果沒有,什麼都不做
  • parallel():將stream轉為並行流,並行流的使用一定要注意安全執行緒

 

 

 

 

八、

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.