.stream().flatMap
.stream().flatMap
是 Java Stream API 中的一个方法,用于将嵌套的流展平为一个单一的流。它通常用于处理包含集合的集合,例如列表中的列表。
方法解释
.stream()
:将集合转换为流。.flatMap
:这是一个中间操作,用于将流中的每个元素转换为一个新的流,然后将这些流合并为一个单一的流。
使用场景
flatMap
通常用于处理嵌套的集合结构,例如列表中的列表。它可以将嵌套的集合展平为一个单一的集合。
示例
假设你有一个包含多个列表的列表,你希望将这些列表中的所有元素合并为一个单一的列表。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class FlatMapExample {
public static void main(String[] args) {
List<List<String>> listOfLists = Arrays.asList(
Arrays.asList("a", "b", "c"),
Arrays.asList("d", "e", "f"),
Arrays.asList("g", "h", "i")
);
// 使用 flatMap 将嵌套的列表展平为一个单一的列表
List<String> flatList = listOfLists.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
System.out.println(flatList); // 输出: [a, b, c, d, e, f, g, h, i]
}
}
解释
listOfLists.stream()
:将包含多个列表的列表转换为流。.flatMap(List::stream)
:将每个子列表转换为流,并将这些流展平为一个单一的流。.collect(Collectors.toList())
:将展平后的流收集为一个列表。
另一个示例
假设你有一个包含多个句子的列表,你希望将这些句子中的所有单词合并为一个单一的列表。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class FlatMapExample {
public static void main(String[] args) {
List<String> sentences = Arrays.asList(
"Hello world",
"Java Stream API",
"FlatMap example"
);
// 使用 flatMap 将句子中的单词展平为一个单一的列表
List<String> words = sentences.stream()
.flatMap(sentence -> Arrays.stream(sentence.split(" ")))
.collect(Collectors.toList());
System.out.println(words); // 输出: [Hello, world, Java, Stream, API, FlatMap, example]
}
}
解释
sentences.stream()
:将包含多个句子的列表转换为流。.flatMap(sentence -> Arrays.stream(sentence.split(" ")))
:将每个句子拆分为单词,并将这些单词的流展平为一个单一的流。.collect(Collectors.toList())
:将展平后的流收集为一个列表。
通过使用 flatMap
,你可以轻松地将嵌套的集合结构展平为一个单一的集合,从而简化数据处理过程。
CompletableFuture.supplyAsync
CompletableFuture.supplyAsync
是 Java 中 CompletableFuture
类的一个静态方法,用于异步地执行一个任务,并返回一个 CompletableFuture
对象。这个方法通常用于在后台线程中执行耗时操作,而不阻塞主线程。
方法签名
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
参数
supplier
:这是一个Supplier<U>
接口的实例,表示一个不接受任何参数但返回结果的函数。U
是返回结果的类型。
返回值
CompletableFuture<U>
:返回一个CompletableFuture
对象,表示异步计算的结果。
示例
以下是一个使用 CompletableFuture.supplyAsync
的示例,展示如何在后台线程中异步执行一个任务,并在任务完成后处理结果。
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureExample {
public static void main(String[] args) {
// 使用 supplyAsync 在后台线程中异步执行任务
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
// 模拟耗时操作
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Hello, World!";
});
// 主线程可以继续执行其他操作
System.out.println("Task is running asynchronously...");
// 等待异步任务完成并获取结果
try {
String result = future.get(); // 阻塞等待结果
System.out.println("Result: " + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
解释
CompletableFuture.supplyAsync
:在后台线程中异步执行一个任务。任务的逻辑在Supplier
的get
方法中定义,这里模拟了一个耗时操作(睡眠2秒),然后返回字符串"Hello, World!"
。- 主线程继续执行:在异步任务执行的同时,主线程可以继续执行其他操作,不会被阻塞。
future.get()
:阻塞等待异步任务完成,并获取结果。如果任务已经完成,立即返回结果;如果任务尚未完成,阻塞等待直到任务完成。
使用自定义线程池
你还可以使用自定义的线程池来执行异步任务,而不是使用默认的 ForkJoinPool.commonPool()
。
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CompletableFutureExample {
public static void main(String[] args) {
// 创建自定义线程池
ExecutorService executor = Executors.newFixedThreadPool(2);
// 使用 supplyAsync 在自定义线程池中异步执行任务
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
// 模拟耗时操作
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Hello, World!";
}, executor);
// 主线程可以继续执行其他操作
System.out.println("Task is running asynchronously...");
// 等待异步任务完成并获取结果
try {
String result = future.get(); // 阻塞等待结果
System.out.println("Result: " + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
// 关闭线程池
executor.shutdown();
}
}
解释
- 自定义线程池:创建一个固定大小的线程池
ExecutorService
。 supplyAsync
使用自定义线程池:将自定义线程池传递给supplyAsync
方法,使任务在自定义线程池中执行。- 关闭线程池:在任务完成后,关闭线程池以释放资源。
通过使用 CompletableFuture.supplyAsync
,你可以轻松地在后台线程中异步执行任务,从而提高应用程序的响应性和性能。
CompletableFuture.allOf(futures).get();
CompletableFuture.allOf(futures).get();
是 Java 中 CompletableFuture
类的一个方法调用,用于等待多个 CompletableFuture
对象全部完成。以下是对这段代码的详细解释:
方法解释
-
CompletableFuture.allOf
:这是一个静态方法,用于创建一个新的CompletableFuture
,该CompletableFuture
在所有给定的CompletableFuture
完成后完成。其签名如下:public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs)
- 参数:一个或多个
CompletableFuture
对象。 - 返回值:一个新的
CompletableFuture<Void>
,在所有给定的CompletableFuture
完成后完成。
- 参数:一个或多个
-
.get()
:这是CompletableFuture
类的一个方法,用于阻塞等待CompletableFuture
完成,并返回其结果。如果CompletableFuture
完成时抛出了异常,则该方法会抛出相应的异常。
使用场景
CompletableFuture.allOf
通常用于等待多个异步任务全部完成。例如,你可能有多个并行执行的任务,并希望在所有任务完成后执行某些操作。
示例
以下是一个使用 CompletableFuture.allOf
的示例,展示如何等待多个异步任务全部完成:
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureAllOfExample {
public static void main(String[] args) {
// 创建多个异步任务
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Result of Future 1";
});
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Result of Future 2";
});
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Result of Future 3";
});
// 使用 CompletableFuture.allOf 等待所有任务完成
CompletableFuture<Void> allOf = CompletableFuture.allOf(future1, future2, future3);
try {
// 阻塞等待所有任务完成
allOf.get();
// 所有任务完成后,可以获取每个任务的结果
System.out.println(future1.get()); // 输出: Result of Future 1
System.out.println(future2.get()); // 输出: Result of Future 2
System.out.println(future3.get()); // 输出: Result of Future 3
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
解释
- 创建多个异步任务:使用
CompletableFuture.supplyAsync
创建三个异步任务,每个任务模拟一个耗时操作,并返回一个结果字符串。 CompletableFuture.allOf
:创建一个新的CompletableFuture<Void>
,在所有给定的CompletableFuture
完成后完成。.get()
:阻塞等待所有任务完成。如果所有任务都成功完成,则allOf.get()
返回null
;如果任何一个任务抛出异常,则allOf.get()
会抛出相应的异常。- 获取每个任务的结果:在所有任务完成后,可以使用
future1.get()
、future2.get()
和future3.get()
获取每个任务的结果。
通过使用 CompletableFuture.allOf
,你可以轻松地等待多个异步任务全部完成,并在所有任务完成后执行后续操作。这在处理并行任务时非常有用。