2、常用的流操作方法
2.1 filter
filter函数的方法声明如下:
java.util.stream.Stream#filter
Stream filter(Predicate<? super T> predicate);
该方法接收一个谓词,返回一个流,即filter方法接收的lambda表达式需要满足 ( T -> Boolean )。
示例:从菜单中选出所有是素食的菜品:
List vegetarianDishs = menu.stream().filter( Dish::isVegetarian ) // 使用filter过滤流中的菜品。
.collect(toList()); // 将流转换成List,该方法将在后面介绍。
温馨提示:流的操作可以分成中间件操作和终端操作。中间操作通常的返回结果还是流,并且在调用终端操作之前,并不会立即调用,等终端方法调用后,中间操作才会真正触发执行,该示例中的collect方法为终端方法。
我们类比一下数据库查询操作,除了基本的筛选动作外,还有去重,分页等功能,那java8的流API能支持这些操作吗?
答案当然是肯定。
2.1.1 distinct
distinct,类似于数据库中的排重函数,就是对结果集去重。
例如有一个数值numArr = [1,5,8,6,5,2,6],现在要输出该数值中的所有奇数并且不能重复输出,那该如何实现呢?
Arrays.stream(numArr).filter( a -> a % 2 == 0 ).distinict().forEach(System.out::println);
2.1.2 limit
截断流,返回一个i不超过指定元素个数的流。
还是以上例举例,如果要输出的元素是偶数,不能重复输出,并且只输出1个元素,那又该如何实现呢?
Arrays.stream(numArr).filter( a -> a % 2 == 0 ).distinict().limit(1).forEach(System.out::println);
2.1.3 skip
跳过指定元素,返回剩余元素的流,与limit互补。
2.2 Map
还是类比数据库操作,我们通常可以只选择一个表中的某一列,java8流操作也提供了类似的方法。
例如,我们需要从菜单中提取所有菜品的名称,在java8中我们可以使用如下代码实现:
版本1:List dishNames = menu.stream().map( (Dish d) -> d.getName() ).collect(Collectors.toList());
版本2:List dishNames = menu.stream().map( d -> d.getName() ).collect(Collectors.toList());
版本3:List dishNames = menu.stream().map(Dish::getName).collect(Collectors.toList());
文章的后续部分尽量使用最简洁的lambda表达式。
我们来看一下Stream关于map方法的声明:
Stream map(Function<? super T, ? extends R> mapper)
接受一个函数Function,其函数声明为:T -> R,接收一个T类型的对象,返回一个R类型