1. Stream API概述
Java 8 Stream是Java 8中引入的一个新的API,用于处理集合和数组等数据结构的元素。它允许您在数据集上进行功能性操作,例如过滤、映射、排序等,而不需要编写循环或迭代器等底层代码。
Java 8 Stream与集合不同,它并不是一个数据结构,而是一种可操作的流。流可以是无限的,也可以是有限的。在使用流进行操作时,不会改变原始数据集合中的数据,而是返回一个新的流。
Stream API包含了丰富的操作方法,例如过滤、映射、排序、归约等,使得对数据集合进行操作变得非常方便。Java 8 Stream的使用可以极大地简化代码,并提高代码的可读性和可维护性。
2. 初识Stream API
用一个案例来认识StreamAPI的使用:过滤“J”开头的用户名。
方式一:用传统的循环方式处理
List<String> names = Arrays.asList("John", "Jane", "Bob", "Tom");
//传统Java编码实现找出J开头的人名
List<String> jNames = new ArrayList<>();
for (String name : names){
if (name.startsWith("J")){
jNames.add(name);
}
}
System.out.println(jNames);// 输出:[John, Jane]
方式二:用 Stream API
//使用Stream API实现找出J开头的人名
List<String> filteredNames = names.stream().filter(name -> name.startsWith("J")).collect(Collectors.toList());
System.out.println(filteredNames); // 输出:[John, Jane]
上述代码中采用了两种方式实现了过滤“J”开头的用户名,一种是传统for循环方式,另外一种就是Stream API。可以看到使用Stream方式可以大大简化代码。Stream方式中,先使用stream()方法将集合转换为流,然后使用filter()方法筛选以“J”开头的字符串,最后使用collect()方法将筛选后的结果转换为List集合。
3. 常用Stream API方法
Java 8中常用的Stream API主要包括以下几个:
- filter:过滤流中的元素,只保留符合条件的元素
- map:对流中的元素进行映射,将一个元素映射为另一个元素
- flatMap:对流中的元素进行扁平化映射,将一个元素映射为多个元素
- sorted:对流中的元素进行排序
- distinct:去重,保留流中的不同元素
- limit:限制流中元素的数量
- skip:跳过流中的前N个元素
- forEach:遍历流中的元素
- reduce:对流中的元素进行归约,得到一个结果
- collect:将流中的元素收集到一个集合中
- min和max:找出流中的最小值和最大值
- count:统计流中元素的数量
- anyMatch、allMatch和noneMatch:判断流中的元素是否满足某个条件
- findFirst和findAny:找到流中的第一个元素和任意一个元素
- parallel和sequential:切换流的并行和串行模式
上述API定义在集合类和Collectors类上,可以让我们对流进行过滤、映射、排序、去重、统计、归约等常见的操作,并且提供了并行处理的支持,可以充分利用多核处理器的性能,提高程序的执行效率。
4. Stream API的使用步骤
Java 8 Stream API的使用方法主要分为以下几个步骤:
1、创建流
通过集合、数组或者Stream类中提供的静态方法创建流。例如,通过集合创建流:
List<String> list = Arrays.asList("apple", "banana", "orange");
Stream<String> stream = list.stream();
2、中间操作
对流进行中间操作,可以使用filter、map、flatMap、sorted、distinct、limit、skip等操作。例如,使用filter方法过滤集合中的元素:
stream = stream.filter(s -> s.startsWith("a"));
3、终止操作
对流进行终止操作,可以使用forEach、reduce、collect、min、max、count等操作。例如,使用forEach方法遍历流中的元素:
stream.forEach(System.out::println);
4、并行处理
对于大数据集,可以使用并行流来提高程序的执行效率,可以使用parallel和sequential方法来切换并行和串行模式。例如,使用parallel方法将流转换为并行流:
stream = stream.parallel();
以上是Java 8 Stream API的使用方法,可以通过这些步骤来创建、操作和处理流。需要注意的是,在使用Stream API时,应该避免在操作中修改流中的元素,以免出现意外的结果。
5. Stream API的使用示例
1、筛选数据
筛选数据:筛选以“J”开头的字符串。代码示意如下:
List<String> names = Arrays.asList("John", "Jane", "Bob", "Tom");
List<String> filteredNames = names.stream().filter(name -> name.startsWith("J"))
.collect(Collectors.toList());
System.out.println(filteredNames); // 输出:[John, Jane]
上述代码中,使用stream()方法将集合转换为流,然后使用filter()方法筛选以“J”开头的字符串,最后使用collect()方法将筛选后的结果转换为List集合。
2、映射数据
映射字符串的长度,代码示意如下:
List<String> names = Arrays.asList("John", "Jane", "Bob", "Tom");
List<Integer> nameLengths = names.stream().map(String::length).collect(Collectors.toList());
System.out.println(nameLengths); // 输出:[4, 4, 3, 3]
上述代码中,使用stream()方法将集合转换为流,然后使用map()方法将字符串映射为字符串长度,最后使用collect()方法将映射后的结果转换为List集合。
3、统计数据
统计数据,代码示意如下:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
long count = numbers.stream().count();
int max = numbers.stream().max(Integer::compare).orElse(0);
int min = numbers.stream().min(Integer::compare).orElse(0);
int sum = numbers.stream().mapToInt(Integer::intValue).sum();
double average = numbers.stream().mapToInt(Integer::intValue).average().orElse(0.0);
System.out.println("Count: " + count); // 输出:Count: 5
System.out.println("Max: " + max); // 输出:Max: 5
System.out.println("Min: " + min); // 输出:Min: 1
System.out.println("Sum: " + sum); // 输出:Sum: 15
System.out.println("Average: " + average); // 输出:Average: 3.0
上述代码中,使用count()方法统计流中元素的个数,使用max()和min()方法求出流中的最大值和最小值,使用sum()方法求出流中元素的总和,使用average()方法求出流中元素的平均值。
4、排序数据
实现数据排序,代码示意如下:
List<Integer> numbers = Arrays.asList(3, 2, 1, 5, 4);
List<Integer> sortedNumbers = numbers.stream().sorted().collect(Collectors.toList());
System.out.println(sortedNumbers); // 输出:[1, 2, 3, 4, 5]
上述代码中,使用sorted()方法对流中的元素进行排序,最后使用collect()方法将排序后的结果转换为List集合。
以上是一些Java 8 Stream API的基本案例,这些案例只是展示了Stream API的基本用法,还有更多丰富的操作可以使用,例如归约、去重、分组、分区等。