但在当今这个数据大爆炸的时代,在数据来源多样化、数据海量化的今天,不少时候不得不脱离 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/