欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java8函數(shù)式編程應(yīng)用小結(jié)

 更新時(shí)間:2023年12月23日 09:19:43   作者:紅文  
Java8非常重要的就是引入了函數(shù)式編程的思想,使得這門經(jīng)典的面向?qū)ο笳Z言有了函數(shù)式的編程方式,彌補(bǔ)了很大程度上的不足,函數(shù)式思想在處理復(fù)雜問題上有著更為令人稱贊的特性,本文給大家介紹Java8函數(shù)式編程應(yīng)用小結(jié),感興趣的朋友一起看看吧

我們經(jīng)常提到,Java8是革命性的一個(gè)版本,原因就是正式引入了函數(shù)式編程,那Java的函數(shù)式編程在實(shí)際應(yīng)用中到底有什么用呢?結(jié)合實(shí)際的應(yīng)用,我整理出了函數(shù)式在Java的幾個(gè)經(jīng)典用途。

緩求值

惰性求值(Lazy evaluation)是在需要時(shí)才進(jìn)行求值的計(jì)算方式。惰性求值自然地在數(shù)據(jù)結(jié)構(gòu)中包含遞歸,可以以簡單的方式表示無限的概念,這種方式有利于程序的模塊化。

在Java這種Strict語言中,我們定義了臨時(shí)變量代碼塊就會(huì)立即運(yùn)算并且取得結(jié)果,而實(shí)際上很多結(jié)果未必會(huì)使用到,就存在不必要的計(jì)算,如下面的代碼

/**
     * 是否是標(biāo)準(zhǔn)或默認(rèn)工作臺(tái)
     * 理論上僅判斷默認(rèn)工作臺(tái)即可(因?yàn)闃?biāo)準(zhǔn)就是默認(rèn)),此處是兜底一下歷史邏輯
     *
     * @param context
     * @return
     */
    public boolean isStandardOrDefaultWorkbench(SchemaContext context) {
        Supplier<Boolean> isDefaultWorkbench = () -> StringUtils.isNotBlank(context.getDefaultAppUuid())
            && StringUtils.equals(context.getAppUuid(), context.getDefaultAppUuid());
        return WorkbenchType.WORKBENCH.equals(context.getWorkbenchType()) || isDefaultWorkbench.get();
    }

當(dāng)我們使用臨時(shí)變量定義的時(shí)候,需要理解計(jì)算出代碼

StringUtils.isNotBlank(context.getDefaultAppUuid())
    && StringUtils.equals(context.getAppUuid(), context.getDefaultAppUuid())

的值,并用于后面的判斷,不管下面的代碼是否為True,我們都消耗了一次計(jì)算

WorkbenchType.WORKBENCH.equals(context.getWorkbenchType())

而我們使用了Supplier,就可以定義一個(gè)匿名表達(dá)式,只有當(dāng)前面判斷為False的時(shí)候,才會(huì)執(zhí)行

isDefaultWorkbench.get()

,而當(dāng)前面判斷為True的時(shí)候,就不會(huì)執(zhí)行后面的代碼了,通過緩求值的方式,可以節(jié)省在某些情況下的消耗,可以提升系統(tǒng)性能,節(jié)省資源。

高階函數(shù)

高階函數(shù)是指使用其他函數(shù)作為參數(shù)、或者返回一個(gè)函數(shù)作為結(jié)果的函數(shù)。

我們常用的Stream就是典型的流處理思想,可以通過Stream來處理集合并執(zhí)行相關(guān)的操作,其中Stream包含了大量的高階函數(shù),我們可以直接使用匿名表達(dá)式來傳遞業(yè)務(wù)邏輯。值得注意,匿名表達(dá)式本身返回的就是函數(shù),因此匿名表達(dá)式就是一種高階函數(shù)。

 // 過濾隱藏應(yīng)用
        return appDetails.stream().filter(app -> {
            AppModel appModel = new AppModel(app.getAppId(), app.getAppType());
            return !appDisplayModel.getHideApps().contains(appModel);
        }).collect(Collectors.toList());

從上面可以邏輯可以看到,我們可以通過集合的Stream對象進(jìn)行filter、map、collect操作,其中這些高階函數(shù)就可以傳遞lambda表達(dá)式,用于處理我們需要的邏輯。

當(dāng)然除了Stream之外,Java很多工具類也支持外部傳入lambda,比如還有一種常見的工具類Optional。

    /**
     * 獲取組織默認(rèn)工作臺(tái)appUuid
     * @param corpId
     * @param orgConfigTag
     * @return
     */
    public String getDefaultWorkbenchAppUuid(String corpId, OrgConfigTag orgConfigTag) {
        return Optional.ofNullable(orgConfigTag).map(OrgConfigTag::getDefaultAppUuid)
            .orElseGet(() -> OpenPageUtils.buildWorkbenchAppUuid(corpId));
    }

其中的orElseGet方法就支持外部傳入lambda表達(dá)式。

函數(shù)回調(diào)

在計(jì)算機(jī)程序設(shè)計(jì)中,回調(diào)函數(shù),或簡稱回調(diào)(Callback 即call then back 被主函數(shù)調(diào)用運(yùn)算后會(huì)返回主函數(shù)),是指通過參數(shù)將函數(shù)傳遞到其它代碼的,某一塊可執(zhí)行代碼的引用。 這一設(shè)計(jì)允許了底層代碼調(diào)用在高層定義的子程序。

函數(shù)回調(diào)可用于接口兩塊完全無關(guān)的邏輯,比如在A模塊執(zhí)行完畢后,執(zhí)行B模塊,B模塊的代碼事先在A模塊注冊。很多框架型的邏輯,比如統(tǒng)一結(jié)果處理、緩存框架、分布式鎖、線程緩存等都可以通過這個(gè)方式來優(yōu)化,就可以使用lambda的方式來實(shí)現(xiàn)。核心的邏輯就是先處理相關(guān)的通用的中間件邏輯,然后通過lambda來執(zhí)行業(yè)務(wù)邏輯。

/**
     * 創(chuàng)建我的頁面
     *
     * @param corpId
     * @param uid
     */
    protected void createMyPage(String corpId, Long uid, String appUuid, Method method) throws WorkbenchException {
            // 并發(fā)鎖控制
            distributeLockSupport.lockAndDo(key,
                    () -> {
                        //創(chuàng)建頁面方法
                        userCorpPageSupport.createMyPage(corpId, uid);
                        return null;
                    }
            );
    }

如上面的代碼,對于要實(shí)現(xiàn)分布式鎖控制的模塊,可以使用lambda的回調(diào),來實(shí)現(xiàn)加鎖和業(yè)務(wù)邏輯的分離。其中的定義如下述代碼所示

/**
     * 基于緩存的分布式鎖操作
     *
     * @param key      資源key
     * @param callback 回調(diào)函數(shù)
     * @param <T>      返回結(jié)果類型
     * @return
     * @throws Exception
     */
    public <T> T lockAndDo(String key, Callback<T> callback) throws WorkbenchException {
        //取鎖
        ...
        try {
            //加鎖
            ...
            return callback.process();
        } catch (WorkbenchException ex) {
            throw ex;
        }  finally {
            try {
                //釋放鎖
                ...
            } catch (Exception ex) {
                //異常處理
            }
        }
    }
    //回調(diào)接口定義,供外部傳入lambda
    @FunctionalInterface
    public interface Callback<T> {
        /**
         * 回調(diào)處理
         *
         * @return 處理結(jié)果
         * @throws WorkbenchException
         */
        T process() throws WorkbenchException, ServiceException;
    }

自定義函數(shù)

從函數(shù)式編程的核心思想來說,函數(shù)是一等公民,而面向?qū)ο蟮暮诵氖欠庋b??梢酝ㄟ^定義函數(shù)的方式來降低面向?qū)ο竺钍骄幊痰膹?fù)雜度。即盡量把處理邏輯都抽象成可復(fù)用的函數(shù),并通過lambda的方式進(jìn)行調(diào)用。

/**
     * 批量操作
     *
     * @param consumer 函數(shù)式寫法,對批量對象操作
     */
    public void batchProccess(BiConsumer<Long, OrchardDTO> consumer) {
        if(orchardDTOMap!=null && orchardDTOMap.size()>0){
            for (Map.Entry<Long, OrchardDTO> entry : orchardDTOMap.entrySet()) {
                consumer.accept(entry.getKey(), entry.getValue());
            }
        }
    }
public void syncPush(MicroAppContext context, BatchOrchardDTO batchOrchardDTO) {
        //傳入lambda來執(zhí)行邏輯
        batchOrchardDTO.batchProccess((k, v) -> pushFacadeService.push(k, v));
    }

如上圖所示,就是在類中定義了一個(gè)高階函數(shù),在調(diào)用的時(shí)候從外部傳入lambda表達(dá)式,從而實(shí)現(xiàn)batchProccess和pushFacadeService.push兩個(gè)方法的解耦。上面的核心和集合支持lambda是一個(gè)意思,也就是把需要外部頻繁操作的部分抽象出來定義成函數(shù)式接口,以供外部傳入不同的lambda進(jìn)行豐富的操作。

總結(jié)

Java8非常重要的就是引入了函數(shù)式編程的思想,使得這門經(jīng)典的面向?qū)ο笳Z言有了函數(shù)式的編程方式。彌補(bǔ)了很大程度上的不足,函數(shù)式思想在處理復(fù)雜問題上有著更為令人稱贊的特性。

到此這篇關(guān)于Java8函數(shù)式編程應(yīng)用小結(jié)的文章就介紹到這了,更多相關(guān)Java8函數(shù)式編程應(yīng)用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中dubbo+zookeeper微服務(wù)架構(gòu)簡介

    Java中dubbo+zookeeper微服務(wù)架構(gòu)簡介

    Apache Dubbo是一款高性能的 Java RPC 框架,這篇文章主要介紹了Java中dubbo+zookeeper微服務(wù)架構(gòu),需要的朋友可以參考下
    2021-09-09
  • springboot?vue測試平臺(tái)接口定義及發(fā)送請求功能實(shí)現(xiàn)

    springboot?vue測試平臺(tái)接口定義及發(fā)送請求功能實(shí)現(xiàn)

    這篇文章主要為大家介紹了springboot+vue測試平臺(tái)接口定義及發(fā)送請求功能實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • Java 多線程死鎖的產(chǎn)生以及如何避免死鎖

    Java 多線程死鎖的產(chǎn)生以及如何避免死鎖

    這篇文章主要介紹了Java 多線程死鎖的產(chǎn)生以及如何避免死鎖,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Java?Selenium實(shí)現(xiàn)修改打開頁面窗口大小

    Java?Selenium實(shí)現(xiàn)修改打開頁面窗口大小

    Selenium是一個(gè)強(qiáng)大的自動(dòng)化測試工具,支持多種編程語言和瀏覽器,本文將詳細(xì)介紹如何使用Java?Selenium來修改打開頁面窗口的大小,需要的可以參考下
    2025-01-01
  • 關(guān)于java自定義線程池的原理與實(shí)現(xiàn)

    關(guān)于java自定義線程池的原理與實(shí)現(xiàn)

    本文介紹了如何自定義線程池和阻塞隊(duì)列,包括阻塞隊(duì)列的實(shí)現(xiàn)方法,線程池的構(gòu)建以及拒絕策略的應(yīng)用,詳細(xì)闡述了線程池中任務(wù)的提交和執(zhí)行流程,以及如何處理任務(wù)超出隊(duì)列容量的情況
    2022-04-04
  • 深入理解 CAS 算法原理已經(jīng)在jdk中的運(yùn)用

    深入理解 CAS 算法原理已經(jīng)在jdk中的運(yùn)用

    這篇文章主要介紹了深入理解 CAS 算法原理已經(jīng)在jdk中的運(yùn)用,幫助大家更好的使用Java,感興趣的朋友可以了解下
    2020-12-12
  • Java中OkHttp 超時(shí)設(shè)置的實(shí)現(xiàn)

    Java中OkHttp 超時(shí)設(shè)置的實(shí)現(xiàn)

    超時(shí)設(shè)置是網(wǎng)絡(luò)編程中不可忽視的一部分,本文就來介紹一下Java中OkHttp 超時(shí)設(shè)置的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06
  • java編程是做什么的

    java編程是做什么的

    在本篇文章里小編給大家整理的是一篇關(guān)于java編程是什么相關(guān)的基礎(chǔ)知識(shí)點(diǎn)內(nèi)容,有興趣的朋友們可以閱讀下。
    2021-01-01
  • Java?新特性之Option示例詳解

    Java?新特性之Option示例詳解

    使用Optional開發(fā)時(shí)要注意正確使用Optional的“姿勢”,特別注意不要使用3.2節(jié)提到的錯(cuò)誤示范,謹(jǐn)慎使用isPresent()和get()方法,盡量多使用map()、filter()、orElse()等方法來發(fā)揮Optional的作用,對Java??Option相關(guān)知識(shí)感興趣的朋友一起看看吧
    2024-02-02
  • java繪制五子棋棋盤

    java繪制五子棋棋盤

    這篇文章主要為大家詳細(xì)介紹了java繪制五子棋棋盤,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-01-01

最新評(píng)論