Java8的新特性主要是Lambda表达式和流,当流和Lambda表达式结合起来一起使用时,因为流申明式处理数据集合的特点,可以让代码变得简洁易读。
- 流的操作类型主要分为两种:
1.中间操作:
一个流可以后面跟随零个或多个中间操作。其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个操作使用。这类操作都是惰性化的,仅仅调用到这类方法,并没有真正开始流的遍历,真正的遍历需等到终端操作时,常见的中间操作有下面即将介绍的filter、map等
2.终端操作:
一个流有且只能有一个终端操作,当这个操作执行后,流就被关闭了,无法再被操作,因此一个流只能被遍历一次,若想在遍历需要通过源数据在生成流。终端操作的执行,才会真正开始流的遍历。如下面即将介绍的count、collect等 - 流使用:
- 先来看一个示例:
List<Integer> list = Arrays.asList(1, 6, 3, 10, 5, 2, 7, 9, 8, 4);
List<Integer> collect = list.stream()
.filter(num -> num < 6) //筛选出小于4的
.sorted(comparing(Integer::intValue).reversed()) //根据大小倒序
.collect(Collectors.toList());//转换为List
//打印
collect.stream().forEach(System.out::println);
一、中间操作
- filter筛选
List<Integer> integerList = Arrays.asList(1, 1, 2, 3, 4, 5);
Stream<Integer> stream = integerList.stream().filter(i -> i > 3);
- distinct去除重复元素
List<Integer> integerList = Arrays.asList(1, 1, 2, 3, 4, 5);
Stream<Integer> stream = integerList.stream().distinct();
- limit返回指定流个数。(注意:limit的参数值必须>=0,否则将会抛出异常)
List<Integer> integerList = Arrays.asList(1, 1, 2, 3, 4, 5);
Stream<Integer> stream = integerList.stream().limit(3);
- skip跳过流中的元素。(注意:skip的参数值必须>=0,否则将会抛出异常)
List<Integer> integerList = Arrays.asList(1, 1, 2, 3, 4, 5);
Stream<Integer> stream = integerList.stream().skip(2);
- map流映射
List<String> stringList = Arrays.asList("Java 8", "Lambdas", "In", "Action");
Stream<Integer> stream = stringList.stream().map(String::length);
- flatMap流转换
List<String> wordList = Arrays.asList("Hello", "World");
List<String> strList = wordList.stream()
.map(w -> w.split(" "))
.flatMap(Arrays::stream)
.distinct()
.collect(Collectors.toList());
-
元素匹配。(提供了三种匹配方式)
1、allMatch匹配所有
List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
if (integerList.stream().allMatch(i -> i > 3)) {
System.out.println("值都大于3");
}
2、anyMatch匹配其中一个
List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
if (integerList.stream().anyMatch(i -> i > 3)) {
System.out.println("存在大于3的值");
}
3、noneMatch全部不匹配
List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
if (integerList.stream().noneMatch(i -> i > 3)) {
System.out.println("值都小于3");
}
二、终端操作
1、统计流中元素个数
- 通过count
List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
Long result = integerList.stream().count();
- 通过counting
List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
Long result = integerList.stream().collect(counting());
2、查找
- findFirst查找第一个
List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> result = integerList.stream().filter(i -> i > 3).findFirst();
- findAny随机查找一个
List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> result = integerList.stream().filter(i -> i > 3).findAny();
3、获取流中最小最大值
- 通过min/max获取最小最大值
Optional<Integer> min = menu.stream().map(Dish::getCalories).min(Integer::compareTo);
Optional<Integer> max = menu.stream().map(Dish::getCalories).max(Integer::compareTo);
//也可以写成
OptionalInt min = menu.stream().mapToInt(Dish::getCalories).min();
OptionalInt max = menu.stream().mapToInt(Dish::getCalories).max();
- 通过minBy/maxBy获取最小最大值
```java
Optional<Integer> min = menu.stream().map(Dish::getCalories).collect(minBy(Integer::compareTo));
Optional<Integer> max = menu.stream().map(Dish::getCalories).collect(maxBy(Integer::compareTo));