延迟求值是推迟计算到结果真正需要时才执行,跳过无用初始化;java中优先用orelseget替代orelse,stream中前置高效filter、后置高成本操作,spring/c#/kotlin用@lazy/lazy/by lazy封装重对象,python/kotlin/scala用生成器或序列替代eager集合。

延迟求值不是“省掉初始化”,而是“不初始化那些根本用不到的对象”。它通过把计算推迟到结果真正被需要的那一刻,让系统跳过整段无意义的构造逻辑——只要最终没取值,工厂函数、Supplier、构造器、数据库连接、大对象加载,全都不会执行。
优先用 orElseGet 替代 orElse
在 Java 的 Optional 场景中,这是最直接消灭冗余初始化的方式:
-
orElse(expensive()):无论 Optional 是否有值,
expensive()都会立即调用,对象一定被创建 - orElseGet(() -> expensive()):仅当 Optional 为空时才触发 Supplier,否则完全跳过构造逻辑
典型例子:缓存未命中才查库。用 orElseGet(() -> loadFromDB()),缓存命中的请求连数据库连接都不建立。
Stream 操作链里把高成本动作往后压
延迟执行本身不省 CPU,省的是“不该算却算了”的 CPU。关键在于顺序安排:
- 把筛选力度强、开销低的操作(如
filter(x -> x.id > 100))放在最前面,尽早砍掉大量元素 - 把耗资源操作(如
map(x -> callRemoteService(x))或map(x -> parseHeavyJson(x.body)))尽量靠后,甚至包裹进peek()用于调试确认是否真被触发 - 避免
map在filter前:否则所有元素都先做一次昂贵转换,再被过滤掉——纯属浪费
用 Lazy 或语言原生机制封装重对象
对启动时或首次访问前就声明、但未必用得上的大对象,不用等流式处理来救,直接从源头控制初始化时机:
- Java + Spring:在 @Bean 上加
@Lazy,或全局启用spring.main.lazy-initialization=true - C#:用
private readonly Lazy<expensiveservice> _svc = new Lazy<expensiveservice>(Create);</expensiveservice></expensiveservice> - Kotlin:用
by lazy { ExpensiveLoader.load() },默认线程安全,单线程可关锁减开销
这类对象一旦没被任何流操作或业务路径访问到,就永远不会被实例化——内存、IO、CPU 全部节省。
生成器与序列替代 eager 集合
当数据源本身可按需产生,就别一次性全拉进内存:
- Python 用
def data_gen(): yield ...或生成器表达式(x*2 for x in range(10**6)),迭代时才计算每个值 - Kotlin 用
.asSequence()替代.stream()或直接调用map,避免每步都新建中间 List - Scala 用
View或LazyList处理大集合或无限流
这些结构不保存全部结果,只记下“怎么算”,真正要某个元素时才现场生成——对象初始化自然也被延迟到那一瞬间,且只发生一次。










