Stream API
一、简介
Stream API是在Java 8中引入的,为函数式编程提供便利。Stream API的目标是以函数方式处理对象的集合,根据定义,Stream是一个Java组件,可以对其元素进行内部迭代。
Stream(流)接口有终端方法和非终端方法,非终端方法是在流中添加监听器,当调用流的终端方法时,就会开始流元素的内部迭代,并对每个元素调用附加到流上的监听器,结果由终端方法收集。
1、中间方法
Stream接口中的非终端方法称为中间方法(Intermediate Methods),这种方法只能通过调用终端方法来调用。主要的中间方法如下:
-
filter
根据给定的条件从流中过滤掉不需要的元素,此方法接受一个断言(Predicate)并将其应用于每个元素。如果断言函数返回true,则该元素包含在返回的流中。
-
map
根据给定的函数将流的每个元素映射到另一个元素,此方法接受一个函数(Function)并将其应用于每个元素。例如,将流中的每个String元素转换为大写的String元素。
-
flatMap
此方法可用于基于给定函数将流的每个元素映射到多个元素,当需要将复杂对象分解为简单对象时,会使用此方法。例如,将句子列表转换为单词列表。
-
distinct
如果存在重复项,则返回一个唯一元素流。
-
limit
返回指定限制个数的元素。
2、终端方法
当在流上调用终端方法时,迭代在stream或其他stream链上开始;迭代结束后,返回终端方法的结果,终端方法不返回流。
通常,终端方法返回一个值,并在流的每个元素上调用。每个终端函数都采用断言(Predicate)函数,启动元素的迭代,将断言应用于每个元素。主要的终端方法如下:
-
anyMatch
如果任何一个元素满足断言,则返回true;如果所有元素都不满足,则返回falase。
-
allMatch
当所有元素都满足断言时返回true,否则返回false。
-
noneMatch
当所有元素都不满足断言时返回true,否则返回false。
-
collect
将每个元素都存储到传递的集合中。
-
count
返回通过中间方法传递的元素的个数。
-
findAny
返回包含任一元素的Optional实例或空实例(空的stream返回空实例)。
-
findFirst
返回包含第一个元素的Optional实例或空实例。
-
forEach
将Consumer函数应用于每个元素。
-
reduce
使用累加函数对流的元素执行归约(reduction),并返回Optional类型的归约值。
-
min
通过传递的比较器断言比较元素,返回流中的最小元素,是一种特殊的reduction。
-
max
通过传递的比较器断言比较元素,返回流中的最大元素,,是一种特殊的reduction。
-
toArray
返回流中元素的数组。
3、固定长度流
可以通过以下方法创建固定长度的流:
Stream.of()
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
Collection.stream()
List<Integer> nums = Arrays.asList(new Integer[]{1, 2, 3, 4, 5});
Stream<Integer> stream = nums.stream();
Stream.builder()
Builder<Integer> builder = Stream.builder();
builder.accept(1);
builder.accept(2);
builder.accept(3);
builder.accept(4);
builder.accept(5);
Stream<Integer> stream = builder.build();
4、无限流
可以通过以下方法创建无限流:
Stream.iterate()
//3的倍数
Stream<Integer> stream = Stream.iterate(0, n -> n + 3);
stream.limit(10).forEach(System.out::println);
Stream.generate
//生成随机整数流
Stream<Integer> stream = Stream.generate(new Random()::nextInt);
stream.limit(10).forEach(System.out::println);
二、样例
1、中间方法
- 代码
List<String> strs = Arrays.asList("One", "Two", "Three", "Four", "Five", "One");
//filter
Stream<String> longStrs = strs.stream().filter(str -> str.length() > 3);
longStrs.forEach(System.out::println);
//map
strs.stream().map(str -> str.toUpperCase()).forEach(System.out::println);
//flatMap
List<String> sentenceList = Arrays.asList("I am Mahesh.", "I love Java 8 Streams.");
sentenceList.stream().flatMap(sentence -> {return Arrays.asList(sentence.split(" ")).stream();}).forEach(System.out::println);
//distinct
strs.stream().distinct().forEach(System.out::println);
//limit
strs.stream().limit(2).forEach(System.out::println);
- 运行结果
Three
Four
Five
ONE
TWO
THREE
FOUR
FIVE
ONE
I
am
Mahesh.
I
love
Java
8
Streams.
One
Two
Three
Four
Five
One
Two
2、终端方法
- 代码
List<String> strs = Arrays.asList("One", "Two", "Three", "Four", "Five", "One");
//anyMatch
System.out.println(strs.stream().anyMatch(str -> str.contains("ee")));
//allMatch
System.out.println(strs.stream().allMatch(str -> str.length() >= 3));
//noneMatch
System.out.println(strs.stream().noneMatch(str -> str.startsWith("A")));
//collect
strs.stream().filter(str -> str.length() > 3).collect(Collectors.toList()).forEach(System.out::println);;
//findAny
System.out.println(strs.stream().findAny().get());
//findFirst
System.out.println(strs.stream().findFirst().get());
//reduce
System.out.println(strs.stream().reduce((str, another) -> str + " " + another));
//min
System.out.println(strs.stream().min((str, another) -> str.compareTo(another)));
//max
System.out.println(strs.stream().max((str, another) -> str.compareTo(another)));
//toArray
System.out.println(strs.stream().toArray().getClass());
- 运行结果
true
true
true
Three
Four
Five
One
One
Optional[One Two Three Four Five One]
Optional[Five]
Optional[Two]
class [Ljava.lang.Object;