1. Java函數式編程神器 VAVR

        共 13125字,需瀏覽 27分鐘

         ·

        2021-04-25 10:11

        點擊上方藍色字體,選擇“標星公眾號”

        優(yōu)質文章,第一時間送達

        76套java從入門到精通實戰(zhàn)課程分享

        什么是函數式編程

        1、基本概念:他是一種編程范式,對于函數式編程來說,它只關心定義輸入數據和輸出數據相關的關系,數學表達式里面其實是在做一種映射(mapping),輸入的數據和輸出的數據關系是什么樣的,是用函數來定義的。

        2、特征:

              (1)stateless:函數不維護任何狀態(tài)。函數式編程的核心精神是 stateless,簡而言之就是它不能存在狀態(tài),打個比方,你給我數據我處理完扔出來。里面的數據是不變的。

              (2)immutable:輸入數據是不能動的,動了輸入數據就有危險,所以要返回新的數據集。(不可變的)

        Java為什么要函數式編程

        3、優(yōu)勢

        (1)沒有狀態(tài)就沒有傷害。

        (2)并行執(zhí)行無傷害。

        (3)Copy-Paste 重構代碼無傷害。

        (4)函數的執(zhí)行沒有順序上的問題。

        問題所在

        • 函數式相對于普通的java變成來說,如果沒有用過就會直接不清楚這個函數是干什么的,這個是干什么的,如果在團隊中只有部分人使用,那我們在其他人在理解我們的代碼上就會有問題,也就回增加學習成本,和開發(fā)成本。

        • 使用的問題:問題排查的問題 和異常的捕獲的問題。

        EXAMPLE

        package Vavr;

        import com.google.common.collect.Lists;
        import com.google.common.collect.Maps;
        import com.sun.istack.internal.FragmentContentHandler;
        import io.vavr.CheckedFunction0;
        import io.vavr.Function1;
        import io.vavr.Function2;
        import io.vavr.Function3;
        import io.vavr.Lazy;
        import io.vavr.Tuple;
        import io.vavr.Tuple2;
        import io.vavr.control.Either;
        import io.vavr.control.Option;
        import io.vavr.control.Try;
        import java.math.BigInteger;
        import java.util.Arrays;
        import java.util.HashMap;
        import java.util.List;
        import java.util.Map;
        import java.util.Optional;
        import java.util.concurrent.ThreadLocalRandom;
        import javax.annotation.Generated;
        import lombok.Getter;

        /**
         * 函數式編程demo
         *
         * @author yuanxindong
         * @date 4/17/21  7:30 PM
         */
        public class VavrTest {

            /**
             * 元組的使用
             */
            public static void tupleTest() {

                //of 靜態(tài)方法支持使用
                Tuple2<String, Integer> tuple2 = Tuple.of("Hello", 100);

                Tuple2<String, Integer> updatedTuple2 = tuple2.map(String::toUpperCase, v -> v * 5);

                String result = updatedTuple2.apply((str, number) -> String.join(", ",
                    str, number.toString()));

                System.out.println(result);
            }

            /**
             * function函數的使用
             */
            public static void functionTest() {

                // 函數定義,前3個是入參,最后是R
                Function3<Integer, Integer, Integer, Integer> function3 = (v1, v2, v3) -> (v1 + v2) * v3;

                // 函數的組合
                Function3<Integer, Integer, Integer, Integer> composed =
                    function3.andThen(v -> v * 100);

                //執(zhí)行結果
                int result = composed.apply(1, 2, 3);

                System.out.println(result);

                //還有包含部分函數的應用
                Function1<Integer, Integer> function1 = function3.apply(1, 2);

                Integer apply = function1.apply(1);
                System.out.println(apply);

                //項目聯(lián)想
                //結合項目場景使用比如說PDT中定義幾個 函數比如:計算MP時效的函數,計算ALG的函數時效,在定義一些函數結果的拼接等
            }

            /**
             * 柯里化想要解決的問題: 柯里化方法的使用 柯里化的含義: 柯里化(currying)是與λ演算相關的重要概念。通過柯里化,可以把有多個輸入的函數轉換成只有一個輸入的函數,從而可以在λ演算中來表示。 柯里化的名稱來源于數學家 Haskell Curry。Haskell Curry 是一位傳奇性的人物,以他的名字命令了 3 種編程語言,Haskell、Brook 和 Curry。
             * 柯里化是把有多個輸入參數的求值過程,轉換成多個只包含一個參數的函數的求值過程。 對于清單 6 的函數 f(a, b, c),在柯里化之后轉換成函數 g,則對應的調用方式是 g(a)(b)(c)。 函數 (x, y) -> x + y 經過柯里化之后的結果是 x -> (y -> x + y)。
             */
            public static void curriedTest() {
                //設置函數 v1 v
                Function3<Integer, Integer, Integer, Integer> function3 = (v1, v2, v3) -> (v1 + v2) * v3;

                //可以看出來是返回來了一個函數
                Function1<Integer, Function1<Integer, Integer>> apply = function3.curried().apply(1);

                //多次柯里化后就會返回我們想要的記過
                int result = function3.curried().apply(1).curried().apply(2).curried().apply(3);
                System.out.println(result);
            }

            /**
             * 記憶化方法 會將之前計算過的方法進行存儲,相同參數在第二次調用的時候會使用緩存
             */
            public static void memoized() {

                //計算差方
                Function2<BigInteger, Integer, BigInteger> pow = BigInteger::pow;
                //記憶化
                Function2<BigInteger, Integer, BigInteger> memoized = pow.memoized();

                long start = System.currentTimeMillis();
                memoized.apply(BigInteger.valueOf(1024), 1024);
                long end1 = System.currentTimeMillis();

                memoized.apply(BigInteger.valueOf(1024), 1024);
                long end2 = System.currentTimeMillis();
                System.out.printf("%d ms -> %d ms", end1 - start, end2 - end1);
            }

            /**
             * java  8 中的optional  是類似 其目的都是為了避免NPE的出現(xiàn)
             */
            public static void optionTest() {
                //個人覺得option好用的地方在于這個of 靜態(tài)函數。
                Option<String> str = Option.of("Hello");

                str.map(String::length);
                //使用對應的值
                Option<Integer> integers = str.flatMap(v -> Option.of(v.length()));
                boolean empty = integers.isEmpty();
                System.out.println(integers);
            }

            /**
             * either 的使用 包含兩個值,left(異常值) 和 right(正確值)
             */
            public static void eitherAndTryTest() {

                //這個是
                Either<String, String> either =
                    compute()
                        .map(str -> str + " World")
                        .mapLeft(Throwable::getMessage);
                System.out.println(either);

                //Try的使用,不用寫過多的catch,左后將left值交給某一個函數統(tǒng)一處理,
                //在pdt中有很多這樣的代碼,try catch 嵌套起來使用 包含參數定義的參數校驗異常
                //
                Fruit.fromColor("1111");


            }

            private static ThreadLocalRandom random = ThreadLocalRandom.current();

            private static Either<Throwable, String> compute() {
                return random.nextBoolean()
                    ? Either.left(new RuntimeException("Boom!"))
                    : Either.right("Hello");
            }

            @Getter
            public enum Fruit {

                APPLE("APPLE""BLACK"),
                BANANA("BANANA""BLUE"),

                NONE("ORANGE""WHITE");
                private final String name;
                private final String color;

                Fruit(String name, String color) {
                    this.name = name;
                    this.color = color;
                }

                public static Fruit fromColor(String color) {

                    return Try.of(() -> Arrays.stream(Fruit.values())
                        .filter(t -> t.getColor().equals(color))
                        .findFirst().orElse(NONE))
                        .toEither().getOrElse(NONE);
                }

            }


            /**
             * Lazy 表示的是一個延遲計算的值。在第一次訪問時才會進行求值操作,而且該值只會計算一次。之后的訪問操作獲取的是緩存的值。Lazy.of 從接口 Supplier 中創(chuàng)建 Lazy 對象。方法 isEvaluated 可以判斷 Lazy 對象是否已經被求值。
             */
            public static void LazyTest() {
                Lazy<BigInteger> lazy = Lazy.of(() ->
                    BigInteger.valueOf(1024).pow(1024));

                System.out.println(lazy.isEvaluated());
                System.out.println(lazy.get());
                System.out.println(lazy.isEvaluated());
                System.out.println(lazy.get());
                System.out.println(lazy.isEvaluated());
                Lazy<BigInteger> lazy2 = Lazy.of(() ->
                    BigInteger.valueOf(1024).pow(1024));
                System.out.println(lazy2.isEvaluated());
                System.out.println(lazy2.get());

                //未想到應用場景
            }


            public static void main(String[] args) {
                tupleTest();
                functionTest();
                curriedTest();
                memoized();
                LazyTest();
            }

        }

        ————————————————

        版權聲明:本文為CSDN博主「Jeff、yuan」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權協(xié)議,轉載請附上原文出處鏈接及本聲明。

        原文鏈接:

        https://blog.csdn.net/weixin_40413961/article/details/115803185





        粉絲福利:Java從入門到入土學習路線圖

        ??????

        ??長按上方微信二維碼 2 秒


        感謝點贊支持下哈 

        瀏覽 76
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
          
          

            1. www操熟女 | 77777成人综合网站 | 男女免费网站 | 成人性爱视频一区二区 | 无码伦理一区二区三区 |