Java如何實現一個簡化版的Stream框架
Java 的 Stream API 中,延遲執(zhí)行(Lazy Evaluation)的核心在于中間操作不會立即執(zhí)行,而是在遇到終端操作時,整個操作鏈才會執(zhí)行。這種機制通過將中間操作記錄為一系列的操作步驟,只有在需要結果時,才將這些操作應用于數據源。
可以通過記錄操作鏈的思想來模擬 Stream 的延遲執(zhí)行機制。簡單來說,我們可以實現一個自定義的類來存儲這些操作,并在遇到終端操作時一次性執(zhí)行。
下面是一個簡化版的 Stream 實現,展示了如何通過延遲執(zhí)行來處理數據流。
簡單實現的延遲執(zhí)行 Stream 類
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
public class SimpleStream<T> {
private final List<T> source; // 原始數據
private final List<Function<List<T>, List<T>>> operations = new ArrayList<>(); // 用于存儲操作鏈
public SimpleStream(List<T> source) {
this.source = source;
}
// 中間操作:filter
public SimpleStream<T> filter(Predicate<T> predicate) {
operations.add(list -> {
List<T> result = new ArrayList<>();
for (T item : list) {
if (predicate.test(item)) {
result.add(item);
}
}
return result;
});
return this;
}
// 中間操作:map
public <R> SimpleStream<R> map(Function<T, R> mapper) {
// 通過 Function 將當前 SimpleStream 轉換為新類型的 SimpleStream
SimpleStream<R> newStream = new SimpleStream<>(null);
operations.add(list -> {
List<R> result = new ArrayList<>();
for (T item : list) {
result.add(mapper.apply(item));
}
return result;
});
newStream.operations.addAll(this.operations); // 繼承父級操作鏈
return newStream;
}
// 終端操作:forEach,觸發(fā)延遲執(zhí)行
public void forEach(java.util.function.Consumer<T> consumer) {
List<T> result = applyOperations(source); // 在終端操作時應用所有中間操作
for (T item : result) {
consumer.accept(item);
}
}
// 終端操作:collect
public List<T> collect() {
return applyOperations(source); // 在終端操作時應用所有中間操作
}
// 應用所有操作
private List<T> applyOperations(List<T> input) {
List<T> result = input;
for (Function<List<T>, List<T>> operation : operations) {
result = operation.apply(result); // 按順序應用所有的操作
}
return result;
}
// 工廠方法:創(chuàng)建 SimpleStream
public static <T> SimpleStream<T> of(List<T> source) {
return new SimpleStream<>(source);
}
public static void main(String[] args) {
// 示例使用
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
SimpleStream.of(numbers)
.filter(x -> x > 2) // 延遲執(zhí)行的過濾操作
.map(x -> x * 2) // 延遲執(zhí)行的映射操作
.forEach(System.out::println); // 終端操作觸發(fā)執(zhí)行
}
}
代碼說明
- 源數據:
source存儲原始的數據列表,延遲執(zhí)行的所有操作都基于該列表。 - 操作鏈:
operations是一個List<Function<List<T>, List<T>>>,用于存儲中間操作。每個中間操作被表示為一個函數,該函數接收并返回一個列表。 - 中間操作(filter 和 map):這些操作不會立即執(zhí)行,而是將對應的操作邏輯以函數形式存儲在
operations中。filter和map分別通過謂詞和映射函數操作數據。 - 終端操作(forEach 和 collect):終端操作會觸發(fā)數據流的執(zhí)行,在這時,所有的中間操作被按順序應用到原始數據上。
applyOperations()方法負責遍歷operations,依次執(zhí)行操作鏈上的每一個操作。 - 示例:在
main()方法中,鏈式調用filter和map操作,最后通過forEach觸發(fā)計算并打印出結果。
運行結果
6
8
10
總結
- 延遲執(zhí)行的核心思想是將中間操作的邏輯存儲起來,而不立即對數據進行處理。只有在終端操作(如
forEach、collect)被調用時,才會真正執(zhí)行操作鏈中的所有步驟。 - 在這個簡單的實現中,每個中間操作都存儲為一個函數(
Function<List<T>, List<T>>),在終端操作時依次應用這些函數。
這個實現展示了如何通過存儲操作鏈并延遲執(zhí)行來實現類似 Stream 的處理方式。
到此這篇關于Java如何實現一個簡化版的Stream框架的文章就介紹到這了,更多相關Java簡化Stream框架內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringCloud?中防止繞過網關請求直接訪問后端服務的解決方法
這篇文章主要介紹了SpringCloud中如何防止繞過網關請求直接訪問后端服務,本文給大家分享三種解決方案,需要的朋友可以參考下2023-06-06
MyBatis-Plus中的LambdaQuery用法實例詳解
LambdaQueryWrapper是MyBatis-Plus的類型安全查詢工具,通過Lambda表達式簡化條件構建,避免硬編碼字段名,提升代碼可讀性、維護性及重構友好性,適用于單表查詢場景,本文給大家介紹MyBatis-Plus中的LambdaQuery用法,感興趣的朋友一起看看吧2025-07-07
解決IDEA和CMD中java命令提示錯誤: 找不到或無法加載主類的問題
這篇文章主要介紹了解決IDEA和CMD中java命令提示錯誤: 找不到或無法加載主類的問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09

