网站首页 > 精选教程 正文
在Java 8及以后的版本中,Stream API是一个革命性的特性,它为集合框架添加了功能强大的操作。它允许开发者以一种声明式的方式处理数据。Stream API可以极大地简化集合处理代码,并且能够自动支持并行操作。
什么是Stream?
Stream不是一种新的数据结构,而是一种新的方式来对集合中的元素进行操作。它是一种中间操作(如过滤、映射)和终结操作(如查找、归约)的组合,可以用来高效地处理数据集。
Stream的基本操作
- 创建Stream:可以通过Collection的stream()或parallelStream()方法创建。
- 中间操作:如filter(), map(), distinct(), sorted()等。
- 终结操作:如forEach(), reduce(), collect(), min(), max()等。
- 管道操作:多个操作可以链接起来形成流水线。
实践业务场景
假设我们有一个电商系统需要处理大量的订单数据。我们的任务是从一个订单列表中找出所有已支付并且金额超过一定阈值的订单,并且计算这些订单的总金额。
首先定义订单类:
java
深色版本
public class Order {
private String id;
private double amount;
private OrderStatus status;
// Getters and Setters
}
enum OrderStatus {
PAID, UNPAID, CANCELLED
}
接下来,使用Stream API实现上述需求:
java
深色版本
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class OrderProcessor {
public static void main(String[] args) {
// 示例订单列表
List<Order> orders = Arrays.asList(
new Order("001", 250, OrderStatus.PAID),
new Order("002", 99, OrderStatus.UNPAID),
new Order("003", 300, OrderStatus.PAID),
new Order("004", 150, OrderStatus.CANCELLED)
);
// 阈值设定为200元
final double threshold = 200;
// 使用Stream API处理订单
double totalAmount = orders.stream()
.filter(order -> order.getStatus() == OrderStatus.PAID)
.filter(order -> order.getAmount() > threshold)
.mapToDouble(Order::getAmount)
.sum();
System.out.println("Total amount of paid orders over " + threshold + " is: " + totalAmount);
}
}
在这个例子中,我们先通过filter()方法筛选出所有状态为PAID的订单,然后再次使用filter()进一步筛选出金额大于200元的订单。接着,我们使用mapToDouble()转换流中的元素为double类型的流,最后调用sum()来计算总金额。
Java Stream API提供了丰富的API来处理数据流,除了前面提到的一些基本操作外,还有很多其他有用的方法。以下是一些常见的操作以及它们的应用场景:
中间操作
- filter(Predicate<T> predicate):根据提供的谓词过滤流中的元素。
- 示例:orders.stream().filter(o -> o.getStatus() == OrderStatus.PAID)。
- map(Function<T, R> mapper):将流中的每个元素映射到另一个类型。
- 示例:orders.stream().map(Order::getId) 获取订单ID的流。
- flatMap(Function<T, Stream<R>> mapper):将流中的每个值都换成另一个流,然后把这些流连接成一个流。
- 示例:如果你有一个订单列表,每个订单又包含一个产品列表,那么你可以使用flatMap来扁平化这个结构,得到一个单一的产品列表。
- distinct():去除重复元素。
- 示例:在获取唯一ID时很有用,如orders.stream().map(Order::getId).distinct()。
- sorted() 和 sorted(Comparator<T> comparator):排序流中的元素。
- 示例:按订单金额排序 orders.stream().sorted(Comparator.comparing(Order::getAmount))。
- peek(Consumer<T> action):用于调试目的,在流中的每个元素上执行操作。
- 示例:打印流中的每个元素 orders.stream().peek(System.out::println)。
- limit(long maxsize):截取流,使其元素不超过给定数量。
- 示例:只处理前10个订单 orders.stream().limit(10)。
- skip(long n):跳过元素,返回一个扔掉了前n个元素后剩余元素的流。
- 示例:跳过前两个订单 orders.stream().skip(2)。
终结操作
- forEach(Consumer<T> action):对流中的每个元素执行一个动作。
- 示例:遍历订单 orders.stream().forEach(order -> processOrder(order))。
- reduce(T identity, BinaryOperator<T> accumulator) 或 reduce(BinaryOperator<T> accumulator):对流中的元素反复应用一个二元操作,将其减少到单个值。
- 示例:计算订单总金额 orders.stream().reduce(BigDecimal.ZERO, BigDecimal::add)。
- collect(Collector<T,A,R> collector):将流转换为其他形式,例如转换为List、Set、Map等。
- 示例:收集所有已支付订单的ID orders.stream().filter(o -> o.getStatus() == OrderStatus.PAID).map(Order::getId).collect(Collectors.toList())。
- anyMatch/Predicate<T> predicate)、allMatch(Predicate<T> predicate)、noneMatch(Predicate<T> predicate):检查是否至少/全部/没有匹配给定的谓词。
- 示例:检查是否有任何订单金额超过了500元 orders.stream().anyMatch(order -> order.getAmount() > 500)。
- findFirst() 和 findAny():返回第一个或任意一个元素(后者在并行流中更有意义)。
- 示例:找到第一个金额超过500元的订单 orders.stream().filter(order -> order.getAmount() > 500).findFirst()。
- count():返回流中的元素个数。
- 示例:计算已支付订单的数量 orders.stream().filter(o -> o.getStatus() == OrderStatus.PAID).count()。
- max(Comparator<T> comparator) 和 min(Comparator<T> comparator):返回流中的最大/最小元素。
- 示例:找到金额最大的订单 orders.stream().max(Comparator.comparing(Order::getAmount))。
这些操作可以组合在一起使用,以构建复杂的业务逻辑。当使用Stream API时,重要的是要记住,中间操作会返回一个新的流,而终结操作会触发实际的数据处理并关闭流。此外,合理的使用并行流(通过.parallel()方法)可以在处理大量数据时提高性能。
总结
Stream API提供了一种优雅的方式来处理数据集合,使得代码更加简洁易读。在实际开发中,根据业务需求选择合适的方法链,可以让数据处理变得更加高效。
猜你喜欢
- 2024-12-01 5 个 顶级的Java REST API 框架
- 2024-12-01 java 性能优化:35 个小细节,让你提升 java 代码的运行效率
- 2024-12-01 多学习才能多赚钱之:java api 是什么
- 2024-12-01 SpringBoot系列(七):Java8的Stream API,让集合操作更为高效
- 2024-12-01 Java开发人员必知的常用类库,这些你都知道吗?
- 2024-12-01 Excel神具EasyExcel,常见API
- 2024-12-01 java与es8实战:Java API Client有关的知识点串讲
- 2024-12-01 JAVA新特性的入场券-函数式接口
- 2024-12-01 大数据必学Java基础(八):简单介绍API和注释
- 2024-12-01 【Java版源码】YesApi接口管理系统云服务平台——国产软件推荐
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)