但在當今這個數據大爆炸的時代,在數據來源多樣化、數據海量化的今天,不少時候不得不脫離 RDBMS,或者以底層返回的數據爲基礎進行更上層的數據統計。而 Java 的集合 API 中,僅僅有極少許的輔助型方法,更多的時候是程序員須要用 Iterator 來遍歷集合,完成相關的聚合應用邏輯。這是一種遠不夠高效、笨拙的方法。在 Java 7 中,若是要發現 type 爲 grocery 的全部交易,而後返回以交易值降序排序好的交易 ID 集合,咱們須要這樣寫:html
List<Transaction> groceryTransactions = new Arraylist<>(); for(Transaction t: transactions){ if(t.getType() == Transaction.GROCERY){ groceryTransactions.add(t); } } Collections.sort(groceryTransactions, new Comparator(){ public int compare(Transaction t1, Transaction t2){ return t2.getValue().compareTo(t1.getValue()); } }); List<Integer> transactionIds = new ArrayList<>(); for(Transaction t: groceryTransactions){ transactionsIds.add(t.getId()); }
可是若是是stream:java
List<Integer> transactionsIds = transactions.parallelStream(). filter(t -> t.getType() == Transaction.GROCERY). sorted(comparing(Transaction::getValue).reversed()). map(Transaction::getId). collect(toList());
有多種方式生成 Stream Source:程序員
例如:數組
// 1. Individual values Stream stream = Stream.of("a", "b", "c"); // 2. Arrays String [] strArray = new String[] {"a", "b", "c"}; stream = Stream.of(strArray); stream = Arrays.stream(strArray); // 3. Collections List<String> list = Arrays.asList(strArray); stream = list.stream();
對於基本數值型,目前有三種對應的包裝類型 Stream:安全
IntStream、LongStream、DoubleStream數據結構
IntStream.of(new int[]{1, 2, 3}).forEach(System.out::println); IntStream.range(1, 3).forEach(System.out::println); IntStream.rangeClosed(1, 3).forEach(System.out::println);
// 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();
List<String> output = wordList.stream(). map(String::toUpperCase). collect(Collectors.toList());
- filter:過濾全部元素,接受一個返回boolean的表達式 - distinct:去重 - sorted:對 Stream 的排序經過 sorted 進行,它比數組的排序更強之處在於你能夠首先對 Stream 進行各種 map、filter、limit、skip 甚至 distinct 來減小元素數量後,再排序,這能幫助程序明顯縮短執行時間。 sorted(Comparator<? super T> comparator);接受一個Comparator, 如:sorted((p1, p2) -> p1.getName().compareTo(p2.getName())) - peek: 對每一個元素執行操做並返回一個新的 Stream, forEach有一樣的功能,可是foreach是一個終端操做 - limit、 - skip:跳過前X個元素 - parallel、 - sequential、 - unordered - Terminal:終端操做 - forEach : 接受一個表達式,對這個全部元素執行這個表達式 forEachOrdere toArray - reduce:提供一個種子和一個表達式,從種子和全部元素依次執行這個表達式,每次執行的結果都是後一次表達式執行的種子。也能夠沒有種子,則會返回一個Optional。從這個意義上說,字符串拼接、數值的 sum、min、max、average 都是特殊的 reduce。例如 Stream 的 sum 就至關於: ```java // 字符串鏈接,concat = "ABCD" String concat = Stream.of("A", "B", "C", "D").reduce("", String::concat); // 求最小值,minValue = -3.0 double minValue = Stream.of(-1.5, 1.0, -3.0, -2.0).reduce(Double.MAX_VALUE, Double::min); // 求和,sumValue = 10, 有起始值 int sumValue = Stream.of(1, 2, 3, 4).reduce(0, Integer::sum); // 求和,sumValue = 10, 無起始值 sumValue = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get(); // 過濾,字符串鏈接,concat = "ace" concat = Stream.of("a", "B", "c", "D", "e", "F"). filter(x -> x.compareTo("Z") > 0). reduce("", String::concat);
Integer sum = integers.reduce(0, Integer::sum); - collect : java.util.stream.Collectors 類的主要做用就是輔助進行各種有用的 reduction 操做, 例如轉變輸出爲 Collection : collect(Collectors.toList()); 把 Stream 元素進行歸組 : groupingBy/partitioningBy。 - min:找到最小值 - max:找到最大值 - count - anyMatch - allMatch - noneMatch - findFirst - findAny - iterator
String optional = null; Optional.ofNullable(optional).ifPresent(String::toUpperCase); //由於這裏是空值,因此直接跳過 System.out.println("aa"); //這個程序只是打印了這個aa
- findAny: 返回流中的任意一個值 - limit: 返回流中的前X個元素 # 5、Java8 parallelStream是線程不安全的! 解決方案: https://www.cnblogs.com/puyangsky/p/7608741.html 總結就是paralleStream裏直接去修改變量是非線程安全的,可是採用collect和reduce操做就是知足線程安全的了(前提是不干擾源數據,而且與數據處理的順序無關)。 # 6、CompletableFuture相關教程 1. https://colobu.com/2016/02/29/Java-CompletableFuture/ 2. http://songkun.me/2018/05/27/2018-05-26-java8-completablefuture/