系列文章目录
1.SpringBoot整合RabbitMQ并实现消息发送与接收
2. 解析JSON格式参数 & 修改对象的key
3. VUE整合Echarts实现简单的数据可视化
4. List<HashMap<String,String>>实现自定义字符串排序(key排序、Value排序)
5. SpringBoot整合RabbitMQ中交换机的使用(完成消息的发送和接收案例)
文章目录
- 系列文章目录
- 前言
- 一、认识stream流
- 1.1 对比
- 二、具体的区别
- 2.1 普通的方式
- 2.2 stream流
- 三、如何运用stream流
- 3.1 filter(Predicate):
- 3.2 map(Function):
- 3.3 forEach(Consumer):
- 3.4 collect(Collector):
- 3.5 reduce(BinaryOperator):
- 3.6 distinct():
- 3.7 sorted():
- 3.8 limit(long):
- 3.9 skip(long):
- 总结
前言
Stream API 是 Java 8 引入的一个用于处理集合数据的新特性。它可以让开发者以一种更函数式、更简洁的方式对集合进行操作,提供了一套丰富的中间操作和终端操作方法,可以实现过滤、映射、归约等操作,同时支持并行处理,提高了代码的可读性和性能。它的特点有很多,例如惰性求值、函数式编程方式、流水线操作、支持并行处理、内置丰富的中间(map、filter等)、终端(collect等)操作方法。
使用 Stream API 可以简化代码,提高代码的可读性和可维护性。同时,由于其内置的并行处理功能,还可以提高代码的执行效率。在处理集合数据时,特别是需要进行复杂操作或并行处理时,Stream API 是一个非常强大和便捷的工具。下面我们就一起来学习下stream流吧~
一、认识stream流
在前言中,已经简单的介绍了stream流的一些特点,但大家肯定光去看这写特点的话是没有什么感觉的,下面我们就直接先上一段代码,从代码带入到学习理论知识,一起去深入理解和运用stream流。
1.1 对比
我们知道,在不适用stream的情况下,同样的逻辑也可使用普通的循环去实现。那么我们就是用一个简单的方式来带入一下stream流。
我们要实现一个数组[1,2,4,5]让其每个元素的值加一,返回一个新数组
普通方法实现如下::
private List<Integer> fun2(List<Integer> list) {
List<Integer> ss = new ArrayList<>();
for (Integer s : list) {
ss.add(s+1);
}
return ss;
}
是用stream流实现如下:
private List<Integer> fun1(List<Integer> list) {
List<Integer> ss=list.stream().map((key)->{
return key+1;
}).collect(Collectors.toList());
return ss;
}
打印出的效果如下图所示:
可以看到,最终的效果是一样的,但是究竟有什么区别的。我们在什么场景下使用哪种方式会更加好呢?这里我们就来看下他们的区别。
二、具体的区别
2.1 普通的方式
普通的循环使用于在操作简单遍历,精确控制循环控制时使用。
优点:
- 直观性: 传统的循环方式更加直观和易于理解,适合处理简单逻辑和少量数据。
- 精确控制: 可以精确控制循环过程,在一些特殊情况下可能更灵活。
- 性能优化: 在某些情况下,普通的循环方式可能比Stream API更高效,尤其是对于简单的遍历和操作。
缺点:
- 冗余代码: 普通的循环方式需要显式地进行迭代和操作,可能会导致代码量增加。
- 不利于并行处理: 传统循环方式较难实现并行处理,无法充分利用多核处理器的优势。
2.2 stream流
需要对集合数据进行复杂的处理、筛选、转换等操作时,Stream 提供了一种更为简洁、易读和高效的方式。
优点:
- 函数式编程风格: Stream API提供了函数式编程风格的操作,使代码更加简洁和易读。
- 链式调用: 可以通过链式调用一系列操作来处理集合元素,减少了中间变量的使用。
- 内置操作: Stream API提供了丰富的中间操作(如map、filter、sort等)和终端操作(如collect、forEach等),方便进行数据处理和转换。
- 并行处理: Stream API内置支持并行处理,可以自动将任务分配到多个线程上执行,提高处理效率。
缺点:
- 学习曲线: 对于初学者来说,可能需要一定时间来熟悉Stream API的概念和操作方式。
- 性能开销: 在一些情况下,Stream API可能会引入额外的性能开销,尤其是在数据量很大或者处理逻辑复杂的情况下。
三、如何运用stream流
知道了优缺点后,我们来认识下常用的stream流api如何使用,下面我们一个一个理解与结合代码一起学习吧!!!
3.1 filter(Predicate):
作用:过滤符合条件的元素。
案例描述:过滤出长度大于等于 5 的字符串。
输入参数:“apple”, “banana”, “orange”, “pear”, “grape”
输出结果:[apple, banana, orange, grape]
代码如下:
private List<String> fun1(List<String> words) {
List<String> longWords = words.stream()
.filter(word -> word.length() >= 5)
.collect(Collectors.toList());
return longWords;
}
3.2 map(Function):
作用:将元素映射为新的元素。
当使用 map 方法时,你需要传入一个 Function 对象,这个对象用于定义元素的映射关系。下面是一个简单的 Java 案例,演示如何使用 map 方法将元素映射为新的元素:
该方法案例在上述对比时的案例中有运用哦
List ss=list.stream().map((key)->{
return key+1;
}).collect(Collectors.toList());
3.3 forEach(Consumer):
作用:对每个元素执行操作。
foreach相信大家已经很熟悉了吧,当使用 forEach 方法时,你需要传入一个 Consumer 对象,这个对象用于定义对每个元素执行的操作。下面是一个简单的 Java 案例,演示如何使用 forEach 方法对集合中的每个元素执行操作:
案例:遍历list
List<String> words = Arrays.asList("apple", "banana", "orange", "pear", "grape");
//使用 forEach 方法对每个元素执行打印操作
words.forEach(System.out::println);
3.4 collect(Collector):
作用:将 Stream 元素收集到集合中。
collect(Collector) 方法是 Stream API 中用于将 Stream 元素收集到集合中的方法。通过 collect 方法,我们可以将 Stream 中的元素按照指定的规则收集到一个集合中,例如 List、Set、Map 等。
这个在上述案例中也运用到过,所以直接上代码:
List<String> longWords = words.stream()
.filter(word -> word.length() >= 5)
.collect(Collectors.toList());
3.5 reduce(BinaryOperator):
作用:将 Stream 元素归约为一个值。
reduce(BinaryOperator) 方法是 Stream API 中用于将 Stream 元素归约为一个值的方法。通过 reduce 方法,我们可以对 Stream 中的元素进行累积操作,最终得到一个汇总的结果。
// 创建一个包含整数的 Stream
Stream<Integer> numbers = Stream.of(1, 2, 3, 4, 5);
// 使用 reduce 方法将 Stream 元素相加得到总和
int sum = numbers.reduce(0, (a, b) -> a + b);
// 输出归约后的结果
System.out.println("Sum: " + sum); // 输出 Sum: 15
3.6 distinct():
作用:去重,去除重复元素。
distinct() 是 Stream API 中的一个方法,用于去除重复的元素,保留唯一的元素。当应用在一个 Stream 上时,distinct() 方法会返回一个包含不重复元素的新 Stream。注:一般使用Set集合解决比较好理解。
// 创建一个包含重复元素的 Stream
Stream<String> stream = Stream.of("apple", "banana", "apple", "orange", "banana");
// 使用 distinct 方法去除重复元素
Stream<String> distinctStream = stream.distinct();
// 输出去重后的元素
distinctStream.forEach(System.out::println); // 输出 apple, banana, orange
3.7 sorted():
作用:排序,对元素进行排序。
sorted() 方法用于对 Stream 中的元素进行排序,可以使用默认的自然顺序(Comparable 接口)或者自定义排序规则(Comparator 接口)。排序后会返回一个经过排序后的新 Stream。
// 创建一个整数 Stream
Stream<Integer> numbers = Stream.of(5, 3, 8, 1, 2);
// 使用 sorted 方法对元素进行排序
Stream<Integer> sortedStream = numbers.sorted();
// 输出排序后的元素
sortedStream.forEach(System.out::println); // 输出 1, 2, 3, 5, 8
3.8 limit(long):
作用:限制结果集的长度。
limit(long) 方法用于限制结果集的长度,只保留指定数量的元素。当应用在一个 Stream 上时,只会返回前面指定数量的元素,后面的元素将被丢弃。
// 创建一个整数 Stream
Stream<Integer> numbers = Stream.of(1, 2, 8, 4, 5);
// 使用 limit 方法限制结果集的长度为3
Stream<Integer> limitedStream = numbers.limit(3);
// 输出限制长度后的元素
limitedStream.forEach(System.out::println); // 输出 1, 2, 8
3.9 skip(long):
作用:跳过指定数量的元素。
skip(long) 方法用于跳过指定数量的元素,返回一个扔掉了前 n 个元素的 Stream。如果 Stream 的长度小于等于 n,则返回一个空 Stream。
// 创建一个整数 Stream
Stream<Integer> numbers = Stream.of(1, 2, 3, 4, 5);
// 使用 skip 方法跳过前面两个元素
Stream<Integer> skippedStream = numbers.skip(2);
// 输出跳过元素后的结果
skippedStream.forEach(System.out::println); // 输出 3, 4, 5
总结
总的来说,Stream 提供了一种简洁而强大的方式来处理集合数据,它具有函数式编程的特性,能够让我们以声明性的方式进行数据处理操作。对于一些简单的api的使用其实也是比较好理解的,大家在实践中多去运用stream流的方式去处理逻辑,方便熟练运用~
不知不觉间写文章已经快2年了,断断续续写了90多篇文章。看到大家留言我很开心,也乐意去帮助初学者去更加的深刻理解知识点。按照我的理解简单的去将知识点分享给大家。有问题大家可以联系我哦~我们一起进步