最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中Supplier延遲生成值的原因及分析

 更新時(shí)間:2026年01月05日 09:12:52   作者:努力學(xué)習(xí)的明  
延遲生成值(LazyValueGeneration)是指將值的計(jì)算或生成過程推遲到真正需要使用該值時(shí)才執(zhí)行,避免不必要的計(jì)算,提升程序的性能和資源利用率,Java中的Supplier和Optional接口可以實(shí)現(xiàn)延遲生成

在編程中,延遲生成值(Lazy Value Generation) 是指將值的計(jì)算或生成過程推遲到真正需要使用該值時(shí)才執(zhí)行。

這一機(jī)制的核心是避免不必要的計(jì)算,提升程序的性能和資源利用率。結(jié)合 SupplierOptional 的使用場景,我們可以從以下幾個(gè)方面理解延遲生成值:

一、核心概念:為什么需要延遲?

假設(shè)你需要一個(gè)默認(rèn)值,但這個(gè)默認(rèn)值的生成可能:

  • 耗時(shí)(如數(shù)據(jù)庫查詢、網(wǎng)絡(luò)請求)。
  • 耗資源(如創(chuàng)建大型對象、復(fù)雜計(jì)算)。
  • 依賴狀態(tài)(如需要先判斷某個(gè)條件是否成立)。

如果提前生成默認(rèn)值,可能會(huì)導(dǎo)致:

  • 性能浪費(fèi):即使最終不需要使用默認(rèn)值(比如 Optional 中有值),也會(huì)白白執(zhí)行計(jì)算。
  • 邏輯錯(cuò)誤:默認(rèn)值的生成可能依賴后續(xù)才會(huì)變化的狀態(tài)。

延遲生成的目標(biāo):僅在必要時(shí)執(zhí)行計(jì)算,減少無意義的開銷。

二、通過Supplier實(shí)現(xiàn)延遲生成

Supplier 是 Java 函數(shù)式接口(@FunctionalInterface),僅定義一個(gè)無參數(shù)方法 get(),用于返回一個(gè)值。

它的關(guān)鍵作用是:將值的生成邏輯封裝在 get(),而不立即執(zhí)行。

示例:模擬耗時(shí)操作

import java.util.Optional;
import java.util.UUID;

public class LazyDemo {
    public static void main(String[] args) {
        Optional<String> optional = Optional.empty(); // 假設(shè)無值

        // 錯(cuò)誤寫法:提前執(zhí)行生成邏輯(無論是否需要)
        String eagerValue = generateEagerly(); // 立即執(zhí)行
        String value1 = optional.orElse(eagerValue); 

        // 正確寫法:延遲執(zhí)行生成邏輯(僅在必要時(shí))
        String value2 = optional.orElseGet(() -> generateLazily()); // 僅當(dāng)optional為空時(shí)執(zhí)行
    }

    // 提前生成(立即執(zhí)行)
    private static String generateEagerly() {
        System.out.println("執(zhí)行提前生成邏輯");
        return UUID.randomUUID().toString();
    }

    // 延遲生成(通過Supplier封裝)
    private static String generateLazily() {
        System.out.println("執(zhí)行延遲生成邏輯");
        return UUID.randomUUID().toString();
    }
}

執(zhí)行結(jié)果對比

當(dāng) optional 為空時(shí):

  • generateEagerly() 會(huì)在調(diào)用 orElse 前就執(zhí)行,輸出 執(zhí)行提前生成邏輯。
  • generateLazily() 僅在調(diào)用 orElseGetoptional 為空時(shí)執(zhí)行,輸出 執(zhí)行延遲生成邏輯。

當(dāng) optional 有值時(shí)(如 Optional.of("有值")):

  • generateEagerly() 仍然會(huì)執(zhí)行(浪費(fèi)計(jì)算)。
  • generateLazily() 不會(huì)執(zhí)行(節(jié)省資源)。

三、延遲生成的典型應(yīng)用場景

1.避免不必要的計(jì)算

// 假設(shè)getExpensiveData()是耗時(shí)操作
Optional<String> data = fetchData(); 

// 錯(cuò)誤:無論data是否有值,都會(huì)執(zhí)行g(shù)etExpensiveData()
String result = data.orElse(getExpensiveData()); 

// 正確:僅當(dāng)data為空時(shí),才執(zhí)行g(shù)etExpensiveData()
String result = data.orElseGet(() -> getExpensiveData()); 

2.依賴上下文的動(dòng)態(tài)默認(rèn)值

public class UserService {
    private final Database database;

    public User getUser(String userId) {
        Optional<User> user = database.queryUser(userId);
        // 僅當(dāng)用戶不存在時(shí),創(chuàng)建默認(rèn)用戶(依賴當(dāng)前時(shí)間)
        return user.orElseGet(() -> createDefaultUser(LocalDateTime.now()));
    }

    private User createDefaultUser(LocalDateTime timestamp) {
        // 需要當(dāng)前時(shí)間作為參數(shù),延遲生成時(shí)才能獲取最新值
        return new User("default", timestamp);
    }
}
  • 如果提前生成默認(rèn)用戶(如 orElse(createDefaultUser(...))),可能使用過時(shí)的時(shí)間戳。
  • 延遲生成時(shí),createDefaultUser 能獲取當(dāng)前最新的上下文數(shù)據(jù)(如實(shí)時(shí)時(shí)間)。

3.流式編程中的延遲計(jì)算

在 Java Stream 中,某些操作(如 filter、map)是惰性的(Lazy),僅在終端操作(如 forEachcollect)時(shí)才執(zhí)行。Supplier 可以配合這種特性優(yōu)化性能:

List<String> data = ...;

// 延遲生成隨機(jī)數(shù),僅在需要時(shí)(如過濾后的數(shù)據(jù)滿足條件)才生成
data.stream()
    .filter(s -> s.startsWith("A"))
    .findFirst()
    .orElseGet(() -> UUID.randomUUID().toString()); // 僅當(dāng)無匹配元素時(shí)生成

四、延遲生成與立即生成的對比

場景延遲生成(orElseGet)立即生成(orElse)
性能僅在必要時(shí)執(zhí)行計(jì)算,節(jié)省資源無論是否需要,均提前執(zhí)行計(jì)算
適用場景默認(rèn)值生成耗時(shí)、依賴動(dòng)態(tài)狀態(tài)默認(rèn)值已提前存在或生成成本極低
代碼可讀性需通過 lambda 封裝邏輯,稍顯復(fù)雜直接傳入值,代碼更簡潔
線程安全性每次調(diào)用 get() 都會(huì)重新計(jì)算(需注意)提前生成一次,后續(xù)使用同一值

五、總結(jié):延遲生成的本質(zhì)

延遲生成值的核心是將計(jì)算邏輯與值的使用時(shí)機(jī)解耦,通過 Supplier 等工具將 “生成值” 的動(dòng)作推遲到真正需要的時(shí)刻。這一思想在 Java 中廣泛應(yīng)用于:

  • Optional 的默認(rèn)值生成(orElseGet)。
  • 流式編程的惰性操作。
  • 框架中的依賴注入(如 Spring 的 Lazy 注解)。
  • 緩存場景的按需加載(如 ConcurrentHashMap.computeIfAbsent)。

通過延遲生成,可以顯著提升程序的效率,避免 “過早計(jì)算” 帶來的性能損耗,尤其在處理高成本操作或動(dòng)態(tài)依賴時(shí)優(yōu)勢明顯。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java中獲取webapp路徑問題詳解

    Java中獲取webapp路徑問題詳解

    這篇文章主要介紹了Java中獲取webapp路徑問題詳解,WebApp是指基于Web的?系統(tǒng)和?應(yīng)用,其作用是向廣大的最終用戶發(fā)布一組復(fù)雜的內(nèi)容和功能,本文詳解了關(guān)于獲取路徑時(shí)候可能出現(xiàn)的問題,需要的朋友可以參考下
    2023-07-07
  • Java編程語言特性和優(yōu)勢

    Java編程語言特性和優(yōu)勢

    這篇文章主要介紹了Java編程語言特性和優(yōu)勢,Java是一門面向?qū)ο缶幊陶Z言,不僅吸收了C++語言的各種優(yōu)點(diǎn),還摒棄了C++里難以理解的多繼承、指針等概念,同時(shí)也增加了垃圾回收機(jī)制,釋放掉不被使用的內(nèi)存空間,解決了管理內(nèi)存空間的煩惱,下面來聊聊Java編程語言特性和優(yōu)勢吧
    2022-01-01
  • Java線程協(xié)作的兩種方式小結(jié)

    Java線程協(xié)作的兩種方式小結(jié)

    Java中線程協(xié)作的最常見的兩種方式是利用Object.wait()、Object.notify()和使用Condition,本文主要介紹了Java線程協(xié)作的兩種方式小結(jié),文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • Java基礎(chǔ)之Unsafe內(nèi)存操作不安全類詳解

    Java基礎(chǔ)之Unsafe內(nèi)存操作不安全類詳解

    Java是面向?qū)ο笳Z言,在使用Java編程時(shí),大多數(shù)情況下都不會(huì)直接操作內(nèi)存,而且Java也不提倡直接操作內(nèi)存,但是Java中到底有沒有可以直接操作內(nèi)存的工具類呢?有!Java中提供Unsafe類可以用來來直接操作內(nèi)存,文中詳細(xì)介紹了Unsafe內(nèi)存操作不安全類,需要的朋友可以參考下
    2021-06-06
  • Java多線程中的ThreadLocal應(yīng)用場景及問題解讀

    Java多線程中的ThreadLocal應(yīng)用場景及問題解讀

    這篇文章主要介紹了Java多線程中的ThreadLocal應(yīng)用場景及問題解讀,ThreadLocal這個(gè)類在多線程并發(fā)中主要的使用場景是什么呢,我們都知道多線程并發(fā)問題實(shí)際就是多個(gè)線程對公共資源訪問和修改問題,需要的朋友可以參考下
    2023-12-12
  • Java泛型繼承原理與用法詳解

    Java泛型繼承原理與用法詳解

    這篇文章主要介紹了Java泛型繼承原理與用法,結(jié)合實(shí)例形式分析了java泛型繼承的相關(guān)原理與實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2019-07-07
  • SpringBoot算法實(shí)現(xiàn)數(shù)據(jù)加密傳輸

    SpringBoot算法實(shí)現(xiàn)數(shù)據(jù)加密傳輸

    這篇文章主要為大家詳細(xì)介紹了SpringBoot算法實(shí)現(xiàn)數(shù)據(jù)加密傳輸?shù)南嚓P(guān)知識(shí),本文主要是混合加密,前端 SM2 + SM4,后端 Spring Boot + Hutool 解密,希望對大家有所幫助
    2026-03-03
  • Java自定義注解導(dǎo)入和導(dǎo)出合并一對多單元格工具類方式

    Java自定義注解導(dǎo)入和導(dǎo)出合并一對多單元格工具類方式

    文章主要介紹了excel工具類對poi的封裝,包括導(dǎo)入依賴、創(chuàng)建注解、IExcelUtils工具類代碼等內(nèi)容,示例通過訂單、訂單明細(xì)、追溯碼三類實(shí)體進(jìn)行導(dǎo)入和導(dǎo)出測試,展示了日期轉(zhuǎn)換、排序、隱藏字段等功能的應(yīng)用
    2026-04-04
  • MyBatis注解CRUD與執(zhí)行流程深入探究

    MyBatis注解CRUD與執(zhí)行流程深入探究

    這篇文章主要介紹了MyBatis注解CRUD與執(zhí)行流程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-02-02
  • Java String轉(zhuǎn)換時(shí)為null的解決方法

    Java String轉(zhuǎn)換時(shí)為null的解決方法

    這篇文章主要介紹了Java String轉(zhuǎn)換時(shí)為null的解決方法,需要的朋友可以參考下
    2017-07-07

最新評論

平湖市| 克什克腾旗| 梁河县| 方正县| 大新县| 梅河口市| 福海县| 蒙阴县| 砚山县| 银川市| 衢州市| 如皋市| 徐州市| 浙江省| 黄大仙区| 嘉鱼县| 大庆市| 仁怀市| 临洮县| 高雄市| 博爱县| 海门市| 莱州市| 漯河市| 巩义市| 东乡族自治县| 嘉善县| 五河县| 秦安县| 宝鸡市| 铜梁县| 安仁县| 平定县| 沧州市| 保康县| 南和县| 长宁县| 龙陵县| 平泉县| 赤水市| 临海市|