学着使用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 的特性能够概括为: