學着使用stream api,並作一些總結java
很好的中文文檔 https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/api
當咱們使用一個流的時候,一般包括三個基本步驟:數組
獲取一個數據源(source)→ 數據轉換→執行操做獲取想要的結果,每次轉換原有 Stream 對象不改變,返回一個新的 Stream 對象(能夠有屢次轉換),這就容許對其操做能夠像鏈條同樣排列,變成一個管道。數據結構
常見用法多線程
流的操做類型分爲兩種:less
常見案例ide
一個很簡單的例子,涉及map,collect,forEach函數
List<String> wordList = Arrays.asList("a", "b", "c"); //map把留轉換爲一個新的對象返回,collect收集器把流中的元素彙總 List<String> output = wordList.stream().map(String::toUpperCase).collect(Collectors.toList()); output.forEach(System.out::println);
map的使用,它的做用就是把 input Stream 的每個元素,映射成 output Stream 的另一個元素。ui
collect:是一個終端操做,它接收的參數是將流中的元素累積到彙總結果的各類方式(稱爲收集器)spa
預約義收集器包括將流元素歸約和彙總到一個值.以下
工廠方法 |
返回類型 |
用於 |
toList |
List<T> |
把流中全部元素收集到List中 |
示例:List<Menu> menus=Menu.getMenus.stream().collect(Collector.toList()) |
||
toSet |
Set<T> |
把流中全部元素收集到Set中,刪除重複項 |
示例:Set<Menu> menus=Menu.getMenus.stream().collect(Collector.toSet()) |
||
toCollection |
Collection<T> |
把流中全部元素收集到給定的供應源建立的集合中 |
示例:ArrayList<Menu> menus=Menu.getMenus.stream().collect(Collector.toCollection(ArrayList::new)) |
||
Counting |
Long |
計算流中元素個數 |
示例:Long count=Menu.getMenus.stream().collect(counting); |
||
SummingInt |
Integer |
對流中元素的一個整數屬性求和 |
示例:Integer count=Menu.getMenus.stream().collect(summingInt(Menu::getCalories)) |
||
averagingInt |
Double |
計算流中元素integer屬性的平均值 |
示例:Double averaging=Menu.getMenus.stream().collect(averagingInt(Menu::getCalories)) |
||
Joining |
String |
鏈接流中每一個元素的toString方法生成的字符串 |
示例:String name=Menu.getMenus.stream().map(Menu::getName).collect(joining(「, 」)) |
||
maxBy |
Optional<T> |
一個包裹了流中按照給定比較器選出的最大元素的optional |
示例:Optional<Menu> fattest=Menu.getMenus.stream().collect(maxBy(Menu::getCalories)) |
||
minBy |
Optional<T> |
一個包裹了流中按照給定比較器選出的最大元素的optional |
示例: Optional<Menu> lessest=Menu.getMenus.stream().collect(minBy(Menu::getCalories)) |
||
Reducing |
歸約操做產生的類型 |
從一個做爲累加器的初始值開始,利用binaryOperator與流中的元素逐個結合,從而將流歸約爲單個值 |
示例:int count=Menu.getMenus.stream().collect(reducing(0,Menu::getCalories,Integer::sum)); |
||
collectingAndThen |
轉換函數返回的類型 |
包裹另外一個轉換器,對其結果應用轉換函數 |
示例:Int count=Menu.getMenus.stream().collect(collectingAndThen(toList(),List::size)) |
||
groupingBy |
Map<K,List<T>> |
根據流中元素的某個值對流中的元素進行分組,並將屬性值作爲結果map的鍵 |
示例:Map<Type,List<Menu>> menuType=Menu.getMenus.stream().collect(groupingby(Menu::getType)) |
||
partitioningBy |
Map<Boolean,List<T>> |
根據流中每一個元素應用謂語的結果來對項目進行分區 |
示例:Map<Boolean,List<Menu>> menuType=Menu.getMenus.stream().collect(partitioningBy(Menu::isType)); |
forEach 方法接收一個 Lambda 表達式,而後在 Stream 的每個元素上執行該表達式。
filter的使用
Integer[] sixNuMS = {1, 2, 3, 4, 5, 6}; List<Integer> evens = Stream.of(sixNuMS).filter(n->n%2==0).collect(Collectors.toList()); evens.forEach(System.out::println);
reduce的使用
//拼接字符串 String concact = Stream.of("A","B","C","D").reduce("",String::concat); System.out.println(concact); //求最小值 double minValue = Stream.of(1.5,1.0,2.0,-3.0,-2.1).reduce(Double.MAX_VALUE,Double::min); System.out.println(minValue); //求和 int sumValue = Stream.of(1,2,3,4).reduce(Integer::sum).get(); System.out.println(sumValue);
這個方法的主要做用是把 Stream 元素組合起來。它提供一個起始值(種子),而後依照運算規則(BinaryOperator),和前面 Stream 的第一個、第二個、第 n 個元素組合
sorted的使用
List<Integer> list = Arrays.asList(1, 5, 7, 9, 3, 4); List<Integer> list2 = list.stream().sorted((a, b) -> a.compareTo(b)).limit(4).collect(Collectors.toList()); System.out.println(list2);
對 Stream 的排序經過 sorted 進行,它比數組的排序更強之處在於你能夠首先對 Stream 進行各種 map、filter、limit、skip 甚至 distinct 來減小元素數量後,再排序,這能幫助程序明顯縮短執行時間。
match 的使用
List<Integer> list = Arrays.asList(1, 5, 7, 9, 3, 4); boolean all = list.stream().allMatch(n -> n > 10); System.out.println(all); boolean any = list.stream().anyMatch(n -> n > 10); System.out.println(any); boolean none = list.stream().noneMatch(n -> n > 10); System.out.println(none);
Stream 有三個 match 方法,從語義上說:
總之,Stream 的特性能夠概括爲: