You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java中从固定数量的表达式生成惰性流?

惰性版Stream.of实现方案

问题描述

想要实现和Stream.of()相同的功能,但要求惰性执行——即传入的表达式不会在创建流时立即求值,而是等到流被终端操作触发时才执行。

原有的Stream.of()写法(会立即执行所有表达式):

Stream<MyClass> s = Stream.of(
   expression1(),
   expression2(),
   expression3(),
   ...
);

目前已实现的方式(用Supplier列表存储延迟计算逻辑):

List<Supplier<MyClass>> s = Arrays.asList(
   ()->expression1(),
   ()->expression2(),
   ()->expression3(),
   ...
);

现在希望直接通过流来实现,同时需要解决Supplier作为流元素时的重复执行问题(比如流多次执行终端操作时,Supplier会被重复调用,导致表达式重复执行)。

解决方案

1. 基础惰性流实现

可以将Supplier直接包装进流,通过map触发求值,默认情况下流每次终端操作都会重新执行Supplier逻辑:

Stream<Supplier<MyClass>> supplierStream = Stream.of(
    () -> expression1(),
    () -> expression2(),
    () -> expression3()
);

// 仅当终端操作执行时,才会触发对应表达式的求值
Stream<MyClass> lazyStream = supplierStream.map(Supplier::get);

2. 解决重复执行问题(缓存求值结果)

如果需要避免表达式被重复执行,可以给每个Supplier添加缓存逻辑,确保每个表达式只执行一次。自定义带缓存的包装类:

class CachedSupplier<T> implements Supplier<T> {
    private final Supplier<T> delegate;
    private volatile T value;
    private boolean initialized;

    public CachedSupplier(Supplier<T> delegate) {
        this.delegate = delegate;
    }

    @Override
    public T get() {
        if (!initialized) {
            synchronized (this) {
                if (!initialized) {
                    value = delegate.get();
                    initialized = true;
                }
            }
        }
        return value;
    }
}

用该类创建惰性流,即可保证每个表达式仅执行一次:

Stream<MyClass> lazyCachedStream = Stream.of(
        new CachedSupplier<>(() -> expression1()),
        new CachedSupplier<>(() -> expression2()),
        new CachedSupplier<>(() -> expression3())
).map(Supplier::get);

3. 自定义惰性版of方法(更简洁)

封装工具方法,直接生成带缓存的惰性流,使用方式和Stream.of()一致:

public static <T> Stream<T> lazyOf(Supplier<T>... suppliers) {
    return Arrays.stream(suppliers)
            .map(CachedSupplier::new)
            .map(Supplier::get);
}

调用示例:

Stream<MyClass> s = lazyOf(
        () -> expression1(),
        () -> expression2(),
        () -> expression3()
);

内容的提问来源于stack exchange,提问作者Dims

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 13:20:29