集合是Java中使用最多的API,几乎每个Java应用程序都会制造和处理集合。集合对于很多编程任务来说都是非常基本的,它们可以让你把数据分组并加以处理。
流是Java API的新成员,它允许你以声明方式处理数据集合,可以把它们看成遍历数据集的高级迭代器 ,流还可以透明地并行处理。
在java8之前集合迭代有两种方式
一是通用的for 循环模式是在集合上进行迭代, 然后处理返回的每一个元素,如下代码
List<String> list = Arrays.asList("nodejs", "java", "python", "javascript");
int count = 0;
// 使用for循环
for (String s: list) {
if (s.startsWith("java")) {
count ++;
}
}
二是先调用 iterator 方法, 产生一个新的 Iterator 对象, 进而控制整个迭代过程, 迭代过程通过显式调用 Iterator 对象的 hasNext 和 next方法完成迭代,如下代码
List<String> list = Arrays.asList("nodejs", "java", "python", "javascript");
int count = 0;
// 使用迭代器Iterator
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String s = iterator.next();
if (s.startsWith("java")) {
count ++;
}
}
java8引入stream api,可以使程序员站在更高的抽象层次上对集合进行操作。改用stream api迭代代码如下
List<String> list = Arrays.asList("nodejs", "java", "python", "javascript");
long count = list.stream()
.filter(s -> s.startsWith("java")) // 过滤
.count(); // 计数
可以看出使用stream api函数式编程风格更简洁明了,整个过程拆分成过滤和计数这两个步骤。
常用Stream方法介绍
1、collect(toList(), toSet()) 方法,由 stream 里的值生成一个列表
// 从stream里面的3个字符串组成的list
List<String> list= Stream.of("nodejs", "java", "python").collect(Collectors.toList());
// list = "nodejs", "java", "python"
2、map方法,将一种类型的值转换成另外一种类型的值,变成新的流
// 将流中的字符串都变成大写字符串
List<String> list = Stream.of("nodejs", "java", "python")
.map(string -> string.toUpperCase())
.collect(Collectors.toList());
// list = "NODEJS", "JAVA", "PYTHON"
3、filter方法,遍历数据元素,保留符合条件的元素,过滤掉其他,变成新的流
// 将流中以java开头的字符串保留
List<String> list = Stream.of("nodejs", "java", "python", "javascript")
.filter(str -> str.startsWith("java"))
.collect(Collectors.toList());
// list = "java", "javascript"
4、flatMap方法,将多个 stream 连接成一个 stream
// 将3个流合并成一个流
String[][] array = new String[][]{{"a", "b"}, {"c", "d"}, {"e", "f"}};
List<String> list = Stream.of(array) // 字符串数组流Stream<String[]>
.flatMap(Stream::of) // 使用Stream.of方法将String数组变成Stream<String>,再使用flatMap方法合并
.collect(Collectors.toList());
// list = "a", "b", "c", "d" , "e", "f"
5、max和min方法,求stream 元素的最大值和最小值
int result = Stream.of(10, 22, 3, 14, 55).max(Comparator.naturalOrder()).get();
// result = 55
int result = Stream.of(10, 22, 3, 14, 55).min(Comparator.naturalOrder()).get();
// result = 3
6、reduce方法,将stream一组值生成一个值
// 求最大值
int max = Stream.of(10, 22, 3, 14, 55).reduce(0, (a, b) -> a > b ? a : b);
// 求和
int sum = Stream.of(10, 22, 3, 14, 55).reduce(0, Integer::sum);
// max = 55 , sum = 104
上面reduce方法求max和sum计算过程如下图
此外还有peek、limit、skip、sorted等方法,不一一举例说明。
Stream API 存在大量的链式操作,在实际编程中需要组合使用,从而达到特定的效果。