虽然 Java 8 已经发布有一段时间了,可是关于 Java 8 中的 Lambda 表达式最近才开始系统的学习,刚开始就被 Stream 的各类骚操做深深的吸引住了,简直漂亮的不像 Java。我认为每个用 Java 的都应该深刻的学习一下,不只能够写出漂亮的代码,更能够对代码进行更深层次的抽象。java
Java 8 中新新增了 Stream(流) 类来简化集合类的使用,Stream 本质上是个接口,接口中定义了不少对 Stream 对象的操做;那 Stream 又是什么呢?咱们知道, Java 中全部的集合都是基于 Collection 接口的扩展,在 Java 8 中新增了 stream() 方法来获取 Stream 对象,方法以下:android
default Stream<E> stream() { return StreamSupport.stream(spliterator(), false); }
**注意:default 也是 Java 8 中新引入的关键字,用于定义接口中方法的默认实现 **。程序员
因此 Java 中全部的集合都包含这个方法,咱们能够经过 stream() 方法获取这个集合的 Stream 对象。web
先来看一个简单的使用案例以便更深刻的理解:
对一个 List 求和通常的代码须要这么写:编程
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); int sum = 0; for (int i = 0; i < list.size(); i++) { sum += list.get(i); } System.out.println(sum);
这样的样板代码咱们可能天天都要写个好多遍,很是繁琐,并且容易出错,可读性差,下面改为 Stream 方式:svg
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); int sum = list.stream().reduce(0, (acc, value) -> acc + value); System.out.println(sum);
改为这样一目了然,代码很是干净利索,上面代码先经过 stream() 方法获取 Stream 对象,而后调用 Stream 中的 reduce 方法计算,而后获取结果(这里先不用考虑 reduce 是什么,后面会详细介绍);
上面即是 Stream 的一次简单操做。下面来具体说一下。
Stream 中主要包含以下几个方法:函数式编程
方法名 | 简介 |
---|---|
collect(toList()) | 经过 Stream 生成一个列表 |
map | 将流中的一个值转换成一个新的值 |
filter | 过滤 Stream 中的元素 |
flatMap | 将多个 Stream 链接成一个 Stream |
max | 求最大值 |
min | 求最小值 |
reduce | 从一组值中生成一个新的值 |
上面就是 Stream 中包含的几个主要方法,下面逐一对其介绍:函数
collect(toList()) 的做用是经过一个 Stream 对象生成 List 对象,案例:学习
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); List<Integer> result = list.stream().filter((value) -> value > 2).collect(toList()); result.forEach((value) -> System.out.print(value));
上面的代码先建立了一个 List 对象并初始化,而后筛选出大于 2 的值,输出。
filter 方法的做用是过滤 Stream 中的元素,filter 方法是一个高阶函数,接收一个函数接口做为参数,此高阶函数返回一个 boolean 值,返回 true 的元素会保留下来;
collect(toList()) 方法将 filter 操做返回的 Stream 生成一个 List。spa
高阶函数:接收或返回一个函数接口的函数称为高阶函数。
函数接口:只包含一个函数的接口成为函数接口。
map 函数的做用是将流中的一个值转换成一个新的值,举个例子,咱们要将一个 List 转换成 List ,那么就可使用 map 方法,示例代码:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); List<String> result = list.stream().map(value -> String.format("String:%s", value)).collect(toList()); result.forEach(System.out::print);
map 方法将 Integer 元素转换成 String 并使用 collect(toList()) 方法生成一个新的 List。
System.out::print 是 (value) -> System.out.print(value) 的简化版写法。
##flatMap
flatMap:将多个 Stream 链接成一个 Stream,这个怎么理解呢,举个栗子:
首先定义一个 List 对象,将这个对象中的每个 String 都分割成一个字母并生成一个新的 List 对象,代码:
List<String> list = Arrays.asList("abc", "def", "ghi"); List<Character> result = list.stream().flatMap(value -> { char[] chars = value.toCharArray(); Character[] characters = new Character[chars.length]; for(int i = 0; i < characters.length; i++){ characters[i] = chars[i]; } return Stream.of(characters); }).collect(toList()); result.forEach(System.out::println);
上面代码先遍历 list ,经过 flatMap 函数将每一个 String 元素都生成一个新的 Stream 并将这些 Stream 链接成一个新的 Stream。
求最大值最小值,这个很好理解了,直接看代码:
List<Integer> list = Arrays.asList(0, 1, 2, 3); Comparator<Integer> comparator = (o1, o2) -> o1.compareTo(o2); System.out.println(list.stream().min(comparator).get()); System.out.println(list.stream().max(comparator).get());
min 和 max 函数须要一个 Comparator 对象为参数做为比对依据。
从一组值中生成一个新的值,reduce 函数其实用途很是普遍,做用也比较大,咱们举一个累加的例子:
List<Integer> list = Arrays.asList(0, 1, 2, 3); int count = list.stream().reduce(0, (acc, item) -> acc + item).intValue(); System.out.println(count);
reduce 函数的一个参数为循环的初始值,这里计算累加时初始值为 0,acc 表明已经计算的结果,item 表示循环的每一个元素。
到此 Stream 中的几个经常使用方法就介绍完了,其余方法能够本身 Stream 代码。
我是作 android 开发的,其实 Stream 相关的操做由于低版本系统兼容问题在实际 android 开发中仍是没法使用,但这并不能阻碍咱们 android 开发者对其学习,由于追求进步正是每个程序员最基本的素质。
若是以为还不错的话,欢迎关注个人我的公众号,我会不按期发一些干货文章~
参考文献: [1] Richard Warburton.Java 8 函数式编程.北京:人民邮电出版社,2015年4月