1. 引入流
流是Java API的新成员,它允许你以声明式方式处理数据集合。就现在来说,你可以把它看成遍历数据集的高级迭代器。
流操作
java.util.stream.Stream中的stream接口定义了许多操作。它们可以被分为两大类:中间操作和终端操作。可以被连接起来的流操作称为中间操作,关闭流的操作称为终端操作。
-
filter、map和limit可以连成一条流水线
-
collect触发流水线执行并关闭它
中间操作:filter,map、limit、distinct、sorted等,返回一个流,不会单独执行处理,除非遇到终端操作
终端操作:从流中返回一个结果,结果是任何非流的值,例如:collect、count
流的使用一般包括三件事:
- 一个数据源(如集合)来执行一个查询;
- 一个中间操作链,形成一条流的流水线;
- 一个终端操作,执行流水线,并能生成结果。
流的中间操作和终端操作:
2.使用流
2.1 筛选、切片
2.1.1筛选
用谓词筛选
Stream接口支持filter方法。该操作会接受一个谓词作为参数,并返回一个包括所有符合谓词的元素的流。
例如:
List<Dish> vegetarianMenu = menu.stream()
.filter(Dish::isVegetarian)
.collect(toList());
筛选各异的元素
流支持distinct方法,它会返回一个元素各异的流。例如,以下代码会筛选出列表中所有的偶数,并确保没有重复。
List<Integer> numbers = Arrays.asList(1,2,1,3,3,2,4);
numbers.stream()
.filter(i -> i%2 ==0)
.distinct()
.forEach(System.out::println);
截短流
流支持limit(n)方法,该方法会返回一个不超过给定长度n的流。
例如:
List<Dish> dishes = menu.stream()
.filter(d -> d.getCalories() > 300)
.limit(3)
collect(toList());
跳过元素
流还支持skip(n)方法,返回一个扔掉前n个元素的流。如果流元素不足n个则返回一个空流。
例如:
List<Dish> dishes = menu.stream()
.filter(d -> d.getCalories() > 300)
.skip(2)
collect(toList());
2.2 映射
对流中每一个元素应用函数
流支持map方法,它会接受一个函数作为参数。这个函数会被应用到每个元素上,并将其映射成一个新的元素。
例1:
//提取菜肴名称
List<String> dishNames = menu.stream()
.map(Dish::getName)
.collect(toList());
流的扁平化
对于一个单词表,如何返回一张列表,列出里面各不相同的字符?例如给定单词列表[“Hello”,“World”],要返回列表[“H”,“e”,“l”,“o”,“W”,“r”,“d”]。
最开始的版本可能是这样的:
words.stream()
.map(word -> word.split(""))
.collect(toList());
</