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

Java8實戰(zhàn)之Stream的延遲計算

 更新時間:2021年09月07日 15:43:04   作者:鯤鵬飛九萬里  
JDK中Stream的中間函數(shù)如 filter(Predicate super T>)是惰性求值的,filter并非對流中所有元素調(diào)用傳遞給它的Predicate,下面這篇文章主要給大家介紹了關(guān)于Java8實戰(zhàn)之Stream延遲計算的相關(guān)資料,需要的朋友可以參考下

一、函數(shù)式編程

要被稱為函數(shù)式,函數(shù)或方法不應(yīng)該拋出任何異常。使用Optional<R> 類型作為返回值。

透明性:方法中沒有任何操作會修改現(xiàn)有結(jié)構(gòu)

使用Java8進(jìn)行編程時,盡量使用Stream取代迭代操作。如果遞歸可以更簡潔,且不帶副作用,應(yīng)該使用遞歸替換迭代。

"尾-遞"迭代,不需要在不同的棧楨上保存每次遞歸計算的中間值。目前Java不支持這種優(yōu)化,很多的現(xiàn)代JVM語言,比如Scala和Groovy都支持這種形式遞歸迭代的優(yōu)化。

1.1 示例一:方法中沒有任何操作會修改現(xiàn)有結(jié)構(gòu)

獲取列表的子集:

    public static List<List<Integer>> findAllSubList(List<Integer> list) {
        if (list.size()==0) {
            List<List<Integer>> res = new ArrayList<>();
            res.add(Collections.emptyList());
            return res;
        }
        Integer first = list.get(0);
        List<Integer> subList = list.subList(1, list.size());
        List<List<Integer>> allSubList = findAllSubList(subList);
        List<List<Integer>> allSubList2 = insertAll(first, allSubList);
        return concat(allSubList, allSubList2);
    }
    
    private static List<List<Integer>> concat(List<List<Integer>> allSubList, List<List<Integer>> allSubList2) {
        List<List<Integer>> res = new ArrayList<>(allSubList);
        res.addAll(allSubList2);
        return res;
    }

    private static List<List<Integer>> insertAll(Integer item, List<List<Integer>> allSubList) {
        List<List<Integer>> res = new ArrayList<>();
        for (List<Integer> a : allSubList) {
            List<Integer> oneList = new ArrayList<>(a);
            oneList.add(item);
            res.add(oneList);
        }
        return res;
    }

1.2 實例二:“尾-遞”迭代

求n的階乘:

方案一:迭代

    /**
     * 使用迭代計算階乘
     * r 和 i 在每輪迭代中都會更新
     * @param n
     * @return
     */
    public static int factorialIterator(int n) {
        int r = 1;
        for (int i=1; i<=n; i++) {
            r *= i;
        }
        return r;
    }

方案二:使用遞歸

    /**
     * 使用遞歸 計算階乘
     *  比迭代都效率差:因為每次遞歸都需要創(chuàng)建棧楨
     * @param n
     * @return
     */
    public static int factorialRecursive(int n) {
        return n==1? 1 : n * factorialIterator(n-1);
    }

方案三:使用Stream

    /**
     * 使用Stream 計算階乘
     * @param n
     * @return
     */
    public static int factorialStream(int n) {
        return IntStream.rangeClosed(1, n).reduce(1, (x, y)->x*y);
    }

方案四:遞歸的優(yōu)化:“尾-遞”迭代

    /**
     * 尾-遞 迭代
     * @param n
     * @return
     */
    public static int factorialTailIterator(int n) {
        return factorialTailHelp(1, n);
    }

    /**
     * 尾-遞 迭代遞幫助類
     * @param acc
     * @param n
     * @return
     */
    private static int factorialTailHelp(int acc, int n) {
        return n==1?acc:factorialTailHelp(acc*n, n-1);
    }

二、科里化

科里化:幫助你模塊化函數(shù),提高代碼重用性的技術(shù)。

科里化表示一種將一個帶有n元組參數(shù)的函數(shù)轉(zhuǎn)換成n個一元函數(shù)鏈的方法。

三、函數(shù)式數(shù)據(jù)結(jié)構(gòu)——持久化的

數(shù)據(jù)結(jié)構(gòu)的值始終保持一致,不受其他部分變化的影響。

附加條件:所有使用持久化數(shù)據(jù)結(jié)構(gòu)的用戶都必須遵守這一“不修改“原則。不對返回值就行修改。

四、Stream的延遲計算

創(chuàng)建一個質(zhì)數(shù)列表:

4.1 列表接口

/**
 * @Date 2021/9/5
 * @Author lifei
 */
public interface MyList<T> {

    T head();
    MyList<T> tail();

    MyList<T> filter(Predicate<T> p);

    default boolean isEmpty() {
        return true;
    }
}

4.2 延遲列表

public class LazyList<T> implements MyList<T> {
    final T head;
    final Supplier<MyList<T>> tail;

    public LazyList(T head, Supplier<MyList<T>> tail) {
        this.head = head;
        this.tail = tail;
    }
    @Override
    public T head() {
        return head;
    }

    @Override
    public MyList<T> tail() {
        return tail.get();
    }

    @Override
    public MyList<T> filter(Predicate<T> p) {
        return isEmpty()?this:p.test(head())? new LazyList<>(head, ()->tail().filter(p)):tail().filter(p);
    }

    @Override
    public boolean isEmpty() {
        return false;
    }
}

4.3 創(chuàng)建一個無限延遲的列表

    /**
     * 創(chuàng)建一個無限延遲的列表
     * @param n
     * @return
     */
    public static LazyList<Integer> from(int n) {
        return new LazyList<>(n, ()->from(n+1));
    }

4.4 創(chuàng)建一個無限延遲的質(zhì)數(shù)列表

    /**
     * 創(chuàng)建一個無限循環(huán)的 質(zhì)數(shù)列表
     * @param numbers
     * @return
     */
    public static MyList<Integer> primes(MyList<Integer> numbers) {
        return new LazyList<>(numbers.head(), ()->primes(numbers.tail().filter(n->n%numbers.head()!=0)));
    }

4.5 使用無限延遲的質(zhì)數(shù)列表

    public static void main(String[] args) {
        LazyList<Integer> numbers = from(2);
        Integer res2 = numbers.head();
        Integer res3 = numbers.tail().head();
        Integer res4 = numbers.tail().tail().head();
        System.out.println(res2);
        System.out.println(res3);
        System.out.println(res4);
        System.out.println("創(chuàng)建一個無限延遲的質(zhì)數(shù)列表");
        MyList<Integer> primes = primes(numbers);
        for (int i=0; i<30; i++) {
            if (!primes.isEmpty()){
                System.out.print(primes.head() + ", ");
                primes = primes.tail();
            }
        }
        System.out.println();

    }

總結(jié)

到此這篇關(guān)于Java8實戰(zhàn)之Stream延遲計算的文章就介紹到這了,更多相關(guān)Java8 Stream延遲計算內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java多線程中的wait與notify方法詳解

    Java多線程中的wait與notify方法詳解

    這篇文章主要介紹了Java多線程中的wait與notify方法詳解,線程的調(diào)度是無序的,但有些情況要求線程的執(zhí)行是有序的,因此,我們可以使用 wait() 方法來使線程執(zhí)行有序,需要的朋友可以參考下
    2023-08-08
  • Mybatis中返回主鍵值方式

    Mybatis中返回主鍵值方式

    這篇文章主要介紹了Mybatis中返回主鍵值方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Java自動解壓文件實例代碼

    Java自動解壓文件實例代碼

    Java自動解壓文件實例代碼,需要的朋友可以參考一下
    2013-04-04
  • Java SpringBoot實現(xiàn)文件上傳功能的示例代碼

    Java SpringBoot實現(xiàn)文件上傳功能的示例代碼

    這篇文章主要介紹了如何利用Java SpringBoot實現(xiàn)文件上傳功能,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)有一定幫助,需要的可以參考一下
    2022-03-03
  • Java中使用Lambda表達(dá)式和函數(shù)編程示例

    Java中使用Lambda表達(dá)式和函數(shù)編程示例

    這篇文章介紹了Java中使用Lambda表達(dá)式和函數(shù)編程示例,該文章會演示多個示列,分別是變量聲明上下文中的lambda、return語句上下文中的lambda、賦值上下文中的lambda、lambda在數(shù)組初始值設(shè)定項上下文中的用法等等,需要的朋友可以參考一下
    2021-10-10
  • 深入理解Mybatis二級緩存

    深入理解Mybatis二級緩存

    與一級緩存相比,二級緩存范圍更大了一些,可以被多個SqlSession所共用。下面通過本文帶領(lǐng)大家一起學(xué)習(xí)mybatis二級緩存知識,一起看看吧
    2016-12-12
  • 使用Java實現(xiàn)MySQL數(shù)據(jù)鎖定的策略

    使用Java實現(xiàn)MySQL數(shù)據(jù)鎖定的策略

    在并發(fā)環(huán)境下,多個線程同時對MySQL數(shù)據(jù)庫進(jìn)行讀寫操作可能會導(dǎo)致數(shù)據(jù)沖突和不一致的問題,為了解決這些并發(fā)沖突,我們可以采用數(shù)據(jù)鎖定策略來保證數(shù)據(jù)的一致性和完整性,下面將介紹如何使用Java實現(xiàn)MySQL數(shù)據(jù)鎖定策略,,需要的朋友可以參考下
    2023-08-08
  • SpringBoot對Filter過濾器中的異常進(jìn)行全局處理方案詳解

    SpringBoot對Filter過濾器中的異常進(jìn)行全局處理方案詳解

    這篇文章主要介紹了SpringBoot對Filter過濾器中的異常進(jìn)行全局處理,在SpringBoot中我們通過 @ControllerAdvice 注解和 @ExceptionHandler注解注冊了全局異常處理器,需要的朋友可以參考下
    2023-09-09
  • Netty分布式pipeline管道創(chuàng)建方法跟蹤解析

    Netty分布式pipeline管道創(chuàng)建方法跟蹤解析

    這篇文章主要為大家介紹了Netty分布式pipeline管道創(chuàng)建方法跟蹤解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • 淺談SpringSecurity基本原理

    淺談SpringSecurity基本原理

    今天帶大家了解一下SpringSecurity的基本原理,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)java的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05

最新評論

饶阳县| 汝城县| 惠东县| 潞城市| 常宁市| 寻乌县| 平乐县| 达尔| 建湖县| 淳安县| 遵义县| 英超| 宜宾县| 汝城县| 五指山市| 边坝县| 民勤县| 左权县| 长岭县| 大田县| 富裕县| 砚山县| 临泉县| 屏东县| 绵阳市| 邮箱| 龙海市| 垫江县| 永善县| 库尔勒市| 青川县| 和龙市| 渭源县| 上思县| 日喀则市| 兰州市| 防城港市| 西青区| 登封市| 鄯善县| 社旗县|