Java8的新特性——Stream与completableFuture详解

1.Stream

第一部分:Stream 综述

什么是 Stream: Stream 是 Java 8 引入的用于处理集合的一种抽象工具,它允许我们以更简洁的方式进行数据操作。Stream 本身并不存储数据,而是用于对数据源(如集合、数组等)进行操作的管道。

适用场景: Stream 适用于需要对集合进行复杂数据处理的场景,如过滤、映射、排序、聚合等。它特别适合于处理大量数据时,可以简化代码并提高可读性。

好处

  1. 简洁性:通过声明式的 API,可以减少样板代码。
  2. 可读性:链式调用使得代码逻辑更加清晰。
  3. 性能优化:通过惰性求值和短路操作,可以避免不必要的计算。

第二部分:好处的示例代码对比

示例 1:命令式 vs 声明式

命令式方式

java 复制代码
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
List<String> result = new ArrayList<>();
for (String name : names) {
    if (name.length() > 3) {
        result.add(name);
    }
}
System.out.println(result); // 输出: [Alice, Charlie]

声明式方式

java 复制代码
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
List<String> result = names.stream()
    .filter(name -> name.length() > 3)
    .collect(Collectors.toList());
System.out.println(result); // 输出: [Alice, Charlie]

在这个对比中,声明式方式更加简洁,逻辑一目了然。

示例 2:使用 map 和 collect

命令式方式

java 复制代码
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> uppercasedNames = new ArrayList<>();
for (String name : names) {
    uppercasedNames.add(name.toUpperCase());
}
System.out.println(uppercasedNames); // 输出: [ALICE, BOB, CHARLIE]

声明式方式

java 复制代码
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> uppercasedNames = names.stream()
    .map(String::toUpperCase)
    .collect(Collectors.toList());
System.out.println(uppercasedNames); // 输出: [ALICE, BOB, CHARLIE]

第三部分:Stream 的并行 API

并行流 : Java 8 提供的并行流使得我们可以通过简单的 API 使用多核处理器来提高性能。通过调用 parallelStream() 方法,可以轻松实现并行处理。

示例:使用并行流

java 复制代码
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");

List<String> filteredNames = names.parallelStream()
    .filter(name -> name.startsWith("A"))
    .collect(Collectors.toList());

System.out.println(filteredNames); // 输出: [Alice]

Fork/Join 框架: 并行流背后使用了 Fork/Join 框架,它通过将任务分解成多个子任务,利用多核 CPU 的优势来并行处理。具体来说,Fork/Join 框架使用了一个工作窃取算法,当某个线程完成任务时,它可以"窃取"其他线程的任务来处理。

  • Fork:将任务分解成更小的子任务。
  • Join:合并子任务的结果。

通过这些特性,Java 的并行流能够有效地利用系统资源,提高数据处理的效率。

总结

Stream API 通过简化数据处理过程,提高了代码的可读性和可维护性。而并行 API 则使得在多核处理器上进行高效的数据处理成为可能,进一步提升了性能。

2.completableFuture

第一部分:Future 的介绍

Future 是什么Future 是 Java 提供的一个接口,用于表示异步计算的结果。它提供了一种机制来在未来的某个时间点获取任务的执行结果。

异步 : 异步编程指的是程序在执行某个操作时不需要等待该操作完成,而是可以继续执行其他操作。对于 Future 来说,提交的任务在一个独立的线程中执行,主线程可以继续工作,而不是被阻塞。

阻塞和轮询 : 使用 Future 获取结果时,通常需要调用 get() 方法,这个方法会阻塞当前线程,直到任务完成。如果任务尚未完成,调用 get() 会导致线程进入等待状态,直到结果可用。这种阻塞操作可能导致性能问题。

不支持回调Future 本身不支持回调。当任务完成时,无法直接通知主线程,这会导致回调地狱的问题。如果需要在任务完成后执行某些操作,通常需要在主线程中进行轮询,检查任务是否完成,这种方法繁琐且不优雅。

第二部分:CompletableFuture 的拓展

CompletableFuture 是什么CompletableFutureFuture 的一个扩展,提供了更强大的功能,允许我们以非阻塞的方式处理异步计算结果。

回调方法CompletableFuture 提供了一系列回调方法,如 thenApply()thenAccept()thenRun(),允许我们在任务完成时定义要执行的操作。这使得编写异步代码变得更加简单和可读。

示例:传统的 Future 和 CompletableFuture 的对比

使用 Future

java 复制代码
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<Integer> future = executor.submit(() -> {
    Thread.sleep(1000); // 模拟长时间计算
    return 42;
});

// 阻塞获取结果
try {
    Integer result = future.get(); // 这里会阻塞
    System.out.println("Result: " + result);
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
}

使用 CompletableFuture

java 复制代码
CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {
    try {
        Thread.sleep(1000); // 模拟长时间计算
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return 42;
});

// 非阻塞获取结果,并定义回调
completableFuture.thenAccept(result -> System.out.println("Result: " + result));

回调地狱的改善 : 传统的回调实现往往导致"回调地狱",即代码层层嵌套,难以维护。CompletableFuture 通过链式调用的方式改善了这一问题,使得代码更清晰。

示例:使用 CompletableFuture 的链式调用

java 复制代码
CompletableFuture.supplyAsync(() -> {
    // 计算过程
    return 42;
}).thenApply(result -> {
    // 处理结果
    return result * 2;
}).thenAccept(finalResult -> {
    // 最终处理
    System.out.println("Final Result: " + finalResult);
});

改善的原因CompletableFuture 能够改善回调地狱的原因在于它实现了两个接口:

  1. CompletionStage 接口

    • 提供了一系列的组合方法,可以实现非阻塞的回调。
    • 支持链式调用,减少嵌套。
  2. Future 接口

    • 保留了 Future 的所有特性,可以异步获取结果。

第三部分:总结

CompletableFuture 是 Java 8 引入的重要特性,它在处理异步编程时提供了强大的功能,显著改善了传统 Future 的不足。通过回调方法和链式调用,CompletableFuture 使得异步编程更为简单和可读,有效避免了回调地狱的问题。

在使用 CompletableFuture 时,我们可以轻松定义任务完成后的操作,而无需阻塞当前线程,提升了代码的效率和可维护性。

相关推荐
光子物联单片机12 小时前
C语言基础开发入门系列(八)C语言指针的理解与实战
c语言·开发语言·stm32·单片机·mcu
是苏浙12 小时前
零基础入门C语言之文件操作
c语言·开发语言
盈电智控12 小时前
体力劳动反而更难被AI取代?物联网科技如何守护最后的劳动阵地
开发语言·人工智能·python
隔壁阿布都12 小时前
Spring Boot中的Optional如何使用
开发语言·spring boot·python
小龙报12 小时前
《C语言疑难点 --- C语内存函数专题》
c语言·开发语言·c++·创业创新·学习方法·业界资讯·visual studio
TDengine (老段)12 小时前
TDengine 数学函数 CRC32 用户手册
java·大数据·数据库·sql·时序数据库·tdengine·1024程序员节
心随雨下13 小时前
Tomcat日志配置与优化指南
java·服务器·tomcat
Kapaseker13 小时前
Java 25 中值得关注的新特性
java
wljt13 小时前
Linux 常用命令速查手册(Java开发版)
java·linux·python
撩得Android一次心动13 小时前
Android 四大组件——BroadcastReceiver(广播)
android·java·android 四大组件