溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么在Java中實(shí)現(xiàn)函數(shù)式編程

發(fā)布時(shí)間:2021-04-30 15:35:57 來(lái)源:億速云 閱讀:191 作者:Leah 欄目:開(kāi)發(fā)技術(shù)

本篇文章為大家展示了怎么在Java中實(shí)現(xiàn)函數(shù)式編程,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。

常用的java框架有哪些

1.SpringMVC,Spring Web MVC是一種基于Java的實(shí)現(xiàn)了Web MVC設(shè)計(jì)模式的請(qǐng)求驅(qū)動(dòng)類(lèi)型的輕量級(jí)Web框架。2.Shiro,Apache Shiro是Java的一個(gè)安全框架。3.Mybatis,MyBatis 是支持普通 SQL查詢(xún),存儲(chǔ)過(guò)程和高級(jí)映射的優(yōu)秀持久層框架。4.Dubbo,Dubbo是一個(gè)分布式服務(wù)框架。5.Maven,Maven是個(gè)項(xiàng)目管理和構(gòu)建自動(dòng)化工具。6.RabbitMQ,RabbitMQ是用Erlang實(shí)現(xiàn)的一個(gè)高并發(fā)高可靠AMQP消息隊(duì)列服務(wù)器。7.Ehcache,EhCache 是一個(gè)純Java的進(jìn)程內(nèi)緩存框架。

為什么要使用函數(shù)式編程

函數(shù)式編程更多時(shí)候是一種編程的思維方式,是種方法論。函數(shù)式與命令式編程的區(qū)別主要在于:函數(shù)式編程是告訴代碼你要做什么,而命令式編程則是告訴代碼要怎么做。說(shuō)白了,函數(shù)式編程是基于某種語(yǔ)法或調(diào)用API去進(jìn)行編程。例如,我們現(xiàn)在需要從一組數(shù)字中,找出最小的那個(gè)數(shù)字,若使用用命令式編程實(shí)現(xiàn)這個(gè)需求的話,那么所編寫(xiě)的代碼如下:

public static void main(String[] args) {
    int[] nums = new int[]{1, 2, 3, 4, 5, 6, 7, 8};

    int min = Integer.MAX_VALUE;
    for (int num : nums) {
        if (num < min) {
            min = num;
        }
    }
    System.out.println(min);
}

而使用函數(shù)式編程進(jìn)行實(shí)現(xiàn)的話,所編寫(xiě)的代碼如下:

public static void main(String[] args) {
    int[] nums = new int[]{1, 2, 3, 4, 5, 6, 7, 8};

    int min = IntStream.of(nums).min().getAsInt();
    System.out.println(min);
}

從以上的兩個(gè)例子中,可以看出,命令式編程需要自己去實(shí)現(xiàn)具體的邏輯細(xì)節(jié)。而函數(shù)式編程則是調(diào)用API完成需求的實(shí)現(xiàn),將原本命令式的代碼寫(xiě)成一系列嵌套的函數(shù)調(diào)用,在函數(shù)式編程下顯得代碼更簡(jiǎn)潔、易懂,這就是為什么要使用函數(shù)式編程的原因之一。所以才說(shuō)函數(shù)式編程是告訴代碼你要做什么,而命令式編程則是告訴代碼要怎么做,是一種思維的轉(zhuǎn)變。

說(shuō)到函數(shù)式編程就不得不提一下lambda表達(dá)式,它是函數(shù)式編程的基礎(chǔ)。在Java還不支持lambda表達(dá)式時(shí),我們需要?jiǎng)?chuàng)建一個(gè)線程的話,需要編寫(xiě)如下代碼:

public static void main(String[] args) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("running");
        }
    }).start();
}

而使用lambda表達(dá)式一句代碼就能完成線程的創(chuàng)建,lambda強(qiáng)調(diào)了函數(shù)的輸入輸出,隱藏了過(guò)程的細(xì)節(jié),并且可以接受函數(shù)當(dāng)作輸入(參數(shù))和輸出(返回值):

public static void main(String[] args) {
    new Thread(() -> System.out.println("running")).start();
}

注:箭頭的左邊是輸入,右邊則是輸出。

該lambda表達(dá)式的作用其實(shí)就是返回了Runnable接口的實(shí)現(xiàn)對(duì)象,這與我們調(diào)用某個(gè)方法獲取實(shí)例對(duì)象類(lèi)似,只不過(guò)是將實(shí)現(xiàn)代碼直接寫(xiě)在了lambda表達(dá)式里。我們可以做個(gè)簡(jiǎn)單的對(duì)比:

public static void main(String[] args) {
    Runnable runnable1 = () -> System.out.println("running");
    Runnable runnable2 = RunnableFactory.getInstance();
}

JDK8接口新特性

1.函數(shù)接口,接口只能有一個(gè)需要實(shí)現(xiàn)的方法,可以使用@FunctionalInterface 注解進(jìn)行聲明。如下:

@FunctionalInterface
interface Interface1 {
    int doubleNum(int i);
}

使用lambda表達(dá)式獲取該接口的實(shí)現(xiàn)實(shí)例的幾種寫(xiě)法:

public static void main(String[] args) {
    // 最常見(jiàn)的寫(xiě)法
    Interface1 i1 = (i) -> i * 2;
    Interface1 i2 = i -> i * 2;

    // 可以指定參數(shù)類(lèi)型
    Interface1 i3 = (int i) -> i * 2;

    // 若有多行代碼可以這么寫(xiě)
    Interface1 i4 = (int i) -> {
        System.out.println(i);
        return i * 2;
    };
}

2.比較重要的一個(gè)接口特性是接口的默認(rèn)方法,用于提供默認(rèn)實(shí)現(xiàn)。默認(rèn)方法和普通實(shí)現(xiàn)類(lèi)的方法一樣,可以使用this等關(guān)鍵字:

@FunctionalInterface
interface Interface1 {
    int doubleNum(int i);

    default int add(int x, int y) {
        return x + y;
    }
}

之所以說(shuō)默認(rèn)方法這個(gè)特性比較重要,是因?yàn)槲覀兘柚@個(gè)特性可以在以前所編寫(xiě)的一些接口上提供默認(rèn)實(shí)現(xiàn),并且不會(huì)影響任何的實(shí)現(xiàn)類(lèi)以及既有的代碼。例如我們最熟悉的List接口,在JDK1.2以來(lái)List接口就沒(méi)有改動(dòng)過(guò)任何代碼,到了1.8之后才使用這個(gè)新特性增加了一些默認(rèn)實(shí)現(xiàn)。這是因?yàn)槿绻麤](méi)有默認(rèn)方法的特性的話,修改接口代碼帶來(lái)的影響是巨大的,而有了默認(rèn)方法后,增加默認(rèn)實(shí)現(xiàn)可以不影響任何的代碼。

3.當(dāng)接口多重繼承時(shí),可能會(huì)發(fā)生默認(rèn)方法覆蓋的問(wèn)題,這時(shí)可以去指定使用哪一個(gè)接口的默認(rèn)方法實(shí)現(xiàn),如下示例:

@FunctionalInterface
interface Interface1 {
    int doubleNum(int i);

    default int add(int x, int y) {
        return x + y;
    }
}

@FunctionalInterface
interface Interface2 {
    int doubleNum(int i);

    default int add(int x, int y) {
        return x + y;
    }
}

@FunctionalInterface
interface Interface3 extends Interface1, Interface2 {

    @Override
    default int add(int x, int y) {
        // 指定使用哪一個(gè)接口的默認(rèn)方法實(shí)現(xiàn)
        return Interface1.super.add(x, y);
    }
}

函數(shù)接口

我們本小節(jié)來(lái)看看JDK8里自帶了哪些重要的函數(shù)接口:

怎么在Java中實(shí)現(xiàn)函數(shù)式編程

可以看到上表中有好幾個(gè)接口,而其中最常用的是Function接口,它能為我們省去定義一些不必要的函數(shù)接口,減少接口的數(shù)量。我們使用一個(gè)簡(jiǎn)單的例子演示一下 Function 接口的使用:

import java.text.DecimalFormat;
import java.util.function.Function;

class MyMoney {
    private final int money;

    public MyMoney(int money) {
        this.money = money;
    }

    public void printMoney(Function<Integer, String> moneyFormat) {
        System.out.println("我的存款: " + moneyFormat.apply(this.money));
    }
}

public class MoneyDemo {
    public static void main(String[] args) {
        MyMoney me = new MyMoney(99999999);

        Function<Integer, String> moneyFormat = i -> new DecimalFormat("#,###").format(i);
        // 函數(shù)接口支持鏈?zhǔn)讲僮鳎缭黾右粋€(gè)字符串
        me.printMoney(moneyFormat.andThen(s -> "人民幣 " + s));
    }
}

運(yùn)行以上例子,控制臺(tái)輸出如下:

我的存款: 人民幣 99,999,999

若在這個(gè)例子中不使用Function接口的話,則需要自行定義一個(gè)函數(shù)接口,并且不支持鏈?zhǔn)讲僮?,如下示例?/p>

import java.text.DecimalFormat;

// 自定義一個(gè)函數(shù)接口
@FunctionalInterface
interface IMoneyFormat {
    String format(int i);
}

class MyMoney {
    private final int money;

    public MyMoney(int money) {
        this.money = money;
    }

    public void printMoney(IMoneyFormat moneyFormat) {
        System.out.println("我的存款: " + moneyFormat.format(this.money));
    }
}

public class MoneyDemo {
    public static void main(String[] args) {
        MyMoney me = new MyMoney(99999999);

        IMoneyFormat moneyFormat = i -> new DecimalFormat("#,###").format(i);
        me.printMoney(moneyFormat);
    }
}

然后我們?cè)賮?lái)看看Predicate接口和Consumer接口的使用,如下示例:

public static void main(String[] args) {
    // 斷言函數(shù)接口
    Predicate<Integer> predicate = i -> i > 0;
    System.out.println(predicate.test(-9));

    // 消費(fèi)函數(shù)接口
    Consumer<String> consumer = System.out::println;
    consumer.accept("這是輸入的數(shù)據(jù)");
}

運(yùn)行以上例子,控制臺(tái)輸出如下:

false

這是輸入的數(shù)據(jù)

這些接口一般有對(duì)基本類(lèi)型的封裝,使用特定類(lèi)型的接口就不需要去指定泛型了,如下示例:

public static void main(String[] args) {
    // 斷言函數(shù)接口
    IntPredicate intPredicate = i -> i > 0;
    System.out.println(intPredicate.test(-9));

    // 消費(fèi)函數(shù)接口
    IntConsumer intConsumer = (value) -> System.out.println("輸入的數(shù)據(jù)是:" + value);
    intConsumer.accept(123);
}

運(yùn)行以上代碼,控制臺(tái)輸出如下:

false

輸入的數(shù)據(jù)是:123

有了以上接口示例的鋪墊,我們應(yīng)該對(duì)函數(shù)接口的使用有了一個(gè)初步的了解,接下來(lái)我們演示剩下的函數(shù)接口使用方式:

public static void main(String[] args) {
    // 提供數(shù)據(jù)接口
    Supplier<Integer> supplier = () -> 10 + 1;
    System.out.println("提供的數(shù)據(jù)是:" + supplier.get());

    // 一元函數(shù)接口
    UnaryOperator<Integer> unaryOperator = i -> i * 2;
    System.out.println("計(jì)算結(jié)果為:" + unaryOperator.apply(10));

    // 二元函數(shù)接口
    BinaryOperator<Integer> binaryOperator = (a, b) -> a * b;
    System.out.println("計(jì)算結(jié)果為:" + binaryOperator.apply(10, 10));
}

運(yùn)行以上代碼,控制臺(tái)輸出如下:

提供的數(shù)據(jù)是:11

計(jì)算結(jié)果為:20

計(jì)算結(jié)果為:100

而B(niǎo)iFunction接口就是比Function接口多了一個(gè)輸入而已,如下示例:

class MyMoney {
    private final int money;
    private final String name;

    public MyMoney(int money, String name) {
        this.money = money;
        this.name = name;
    }

    public void printMoney(BiFunction<Integer, String, String> moneyFormat) {
        System.out.println(moneyFormat.apply(this.money, this.name));
    }
}

public class MoneyDemo {
    public static void main(String[] args) {
        MyMoney me = new MyMoney(99999999, "小明");

        BiFunction<Integer, String, String> moneyFormat = (i, name) -> name + "的存款: " + new DecimalFormat("#,###").format(i);
        me.printMoney(moneyFormat);
    }
}

運(yùn)行以上代碼,控制臺(tái)輸出如下:

小明的存款: 99,999,999

方法引用

在學(xué)習(xí)了lambda表達(dá)式之后,我們通常會(huì)使用lambda表達(dá)式來(lái)創(chuàng)建匿名方法。但有的時(shí)候我們僅僅是需要調(diào)用一個(gè)已存在的方法。如下示例:

Arrays.sort(stringsArray, (s1, s2) -> s1.compareToIgnoreCase(s2));

在jdk8中,我們可以通過(guò)一個(gè)新特性來(lái)簡(jiǎn)寫(xiě)這段lambda表達(dá)式。如下示例:

Arrays.sort(stringsArray, String::compareToIgnoreCase);

這種特性就叫做方法引用(Method Reference)。方法引用的標(biāo)準(zhǔn)形式是:類(lèi)名::方法名。(注意:只需要寫(xiě)方法名,不需要寫(xiě)括號(hào))。

目前方法引用共有以下四種形式:

類(lèi)型示例代碼示例對(duì)應(yīng)的Lambda表達(dá)式
引用靜態(tài)方法ContainingClass::staticMethodNameString::valueOf(s) -> String.valueOf(s)
引用某個(gè)對(duì)象的實(shí)例方法containingObject::instanceMethodNamex::toString()() -> this.toString()
引用某個(gè)類(lèi)型的任意對(duì)象的實(shí)例方法ContainingType::methodNameString::toString(s) -> s.toString
引用構(gòu)造方法ClassName::newString::new() -> new String()

下面我們用一個(gè)簡(jiǎn)單的例子來(lái)演示一下方法引用的幾種寫(xiě)法。首先定義一個(gè)實(shí)體類(lèi):

public class Dog {
    private String name = "二哈";
    private int food = 10;

    public Dog() {
    }

    public Dog(String name) {
        this.name = name;
    }

    public static void bark(Dog dog) {
        System.out.println(dog + "叫了");
    }

    public int eat(int num) {
        System.out.println("吃了" + num + "斤");
        this.food -= num;
        return this.food;
    }

    @Override
    public String toString() {
        return this.name;
    }
}

通過(guò)方法引用來(lái)調(diào)用該實(shí)體類(lèi)中的方法,代碼如下:

package org.zero01.example.demo;

import java.util.function.*;

/**
 * @ProjectName demo
 * @Author: zeroJun
 * @Date: 2018/9/21 13:09
 * @Description: 方法引用demo
 */
public class MethodRefrenceDemo {

    public static void main(String[] args) {
        // 方法引用,調(diào)用打印方法
        Consumer<String> consumer = System.out::println;
        consumer.accept("接收的數(shù)據(jù)");

        // 靜態(tài)方法引用,通過(guò)類(lèi)名即可調(diào)用
        Consumer<Dog> consumer2 = Dog::bark;
        consumer2.accept(new Dog());

        // 實(shí)例方法引用,通過(guò)對(duì)象實(shí)例進(jìn)行引用
        Dog dog = new Dog();
        IntUnaryOperator function = dog::eat;
        System.out.println("還剩下" + function.applyAsInt(2) + "斤");

        // 另一種通過(guò)實(shí)例方法引用的方式,之所以可以這么干是因?yàn)镴DK默認(rèn)會(huì)把當(dāng)前實(shí)例傳入到非靜態(tài)方法,參數(shù)名為this,參數(shù)位置為第一個(gè),所以我們?cè)诜庆o態(tài)方法中才能訪問(wèn)this,那么就可以通過(guò)BiFunction傳入實(shí)例對(duì)象進(jìn)行實(shí)例方法的引用
        Dog dog2 = new Dog();
        BiFunction<Dog, Integer, Integer> biFunction = Dog::eat;
        System.out.println("還剩下" + biFunction.apply(dog2, 2) + "斤");

        // 無(wú)參構(gòu)造函數(shù)的方法引用,類(lèi)似于靜態(tài)方法引用,只需要分析好輸入輸出即可
        Supplier<Dog> supplier = Dog::new;
        System.out.println("創(chuàng)建了新對(duì)象:" + supplier.get());

        // 有參構(gòu)造函數(shù)的方法引用
        Function<String, Dog> function2 = Dog::new;
        System.out.println("創(chuàng)建了新對(duì)象:" + function2.apply("旺財(cái)"));
    }
}

最后需要說(shuō)一句的就是能夠使用方法引用的地方就盡量不要使用lambda表達(dá)式,這樣就不會(huì)多生成一個(gè)類(lèi)似 lambda$0這樣的函數(shù),能夠減少一些資源的開(kāi)銷(xiāo)。

類(lèi)型推斷

通過(guò)以上的例子,我們知道之所以能夠使用Lambda表達(dá)式的依據(jù)是必須有相應(yīng)的函數(shù)接口。這一點(diǎn)跟Java是強(qiáng)類(lèi)型語(yǔ)言吻合,也就是說(shuō)你并不能在代碼的任何地方任性的寫(xiě)Lambda表達(dá)式。實(shí)際上Lambda的類(lèi)型就是對(duì)應(yīng)函數(shù)接口的類(lèi)型。Lambda表達(dá)式另一個(gè)依據(jù)是類(lèi)型推斷機(jī)制,在上下文信息足夠的情況下,編譯器可以推斷出參數(shù)表的類(lèi)型,而不需要顯式指名。
所以說(shuō) Lambda 表達(dá)式的類(lèi)型是從 Lambda 的上下文推斷出來(lái)的,上下文中 Lambda 表達(dá)式需要的類(lèi)型稱(chēng)為目標(biāo)類(lèi)型,如下圖所示:

怎么在Java中實(shí)現(xiàn)函數(shù)式編程

接下來(lái)我們使用一個(gè)簡(jiǎn)單的例子,演示一下 Lambda 表達(dá)式的幾種類(lèi)型推斷,首先定義一個(gè)簡(jiǎn)單的函數(shù)接口:

@FunctionalInterface
interface IMath {
    int add(int x, int y);
}

示例代碼如下:

public class TypeDemo {

    public static void main(String[] args) {
        // 1.通過(guò)變量類(lèi)型定義
        IMath iMath = (x, y) -> x + y;

        // 2.數(shù)組構(gòu)建的方式
        IMath[] iMaths = {(x, y) -> x + y};

        // 3.強(qiáng)轉(zhuǎn)類(lèi)型的方式
        Object object = (IMath) (x, y) -> x + y;

        // 4.通過(guò)方法返回值確定類(lèi)型
        IMath result = createIMathObj();

        // 5.通過(guò)方法參數(shù)確定類(lèi)型
        test((x, y) -> x + y);

    }

    public static IMath createIMathObj() {
        return (x, y) -> x + y;
    }

    public static void test(IMath iMath){
        return;
    }
}

變量引用

Lambda表達(dá)式類(lèi)似于實(shí)現(xiàn)了指定接口的內(nèi)部類(lèi)或者說(shuō)匿名類(lèi),所以在Lambda表達(dá)式中引用變量和我們?cè)谀涿?lèi)中引用變量的規(guī)則是一樣的。如下示例:

public static void main(String[] args) {
    String str = "當(dāng)前的系統(tǒng)時(shí)間戳是: ";
    Consumer<Long> consumer = s -> System.out.println(str + s);
    consumer.accept(System.currentTimeMillis());
}

值得一提的是,在JDK1.8之前我們一般會(huì)將匿名類(lèi)里訪問(wèn)的外部變量設(shè)置為final,而在JDK1.8里默認(rèn)會(huì)將這個(gè)匿名類(lèi)里訪問(wèn)的外部變量給設(shè)置為final。例如我現(xiàn)在改變str變量的值,ide就會(huì)提示錯(cuò)誤:

怎么在Java中實(shí)現(xiàn)函數(shù)式編程

怎么在Java中實(shí)現(xiàn)函數(shù)式編程

若此時(shí)list變量指向了另一個(gè)對(duì)象,那么匿名類(lèi)里引用的還是之前那個(gè)值對(duì)象,所以我們才需要將其設(shè)置為final防止外部變量引用改變:

怎么在Java中實(shí)現(xiàn)函數(shù)式編程

而如果是引用傳遞的話,匿名類(lèi)里對(duì)外部變量的引用就不是值對(duì)象了,而是指針指向這個(gè)外部變量:

怎么在Java中實(shí)現(xiàn)函數(shù)式編程

所以就算list變量指向了另一個(gè)對(duì)象,匿名類(lèi)里的引用也會(huì)隨著外部變量的引用改變而改變:

怎么在Java中實(shí)現(xiàn)函數(shù)式編程

級(jí)聯(lián)表達(dá)式和柯里化

在函數(shù)式編程中,函數(shù)既可以接收也可以返回其他函數(shù)。函數(shù)不再像傳統(tǒng)的面向?qū)ο缶幊讨幸粯?,只是一個(gè)對(duì)象的工廠或生成器,它也能夠創(chuàng)建和返回另一個(gè)函數(shù)。返回函數(shù)的函數(shù)可以變成級(jí)聯(lián) lambda 表達(dá)式,特別值得注意的是代碼非常簡(jiǎn)短。盡管此語(yǔ)法初看起來(lái)可能非常陌生,但它有自己的用途。

級(jí)聯(lián)表達(dá)式就是多個(gè)lambda表達(dá)式的組合,這里涉及到一個(gè)高階函數(shù)的概念,所謂高階函數(shù)就是一個(gè)可以返回函數(shù)的函數(shù),如下示例:

// 實(shí)現(xiàn)了 x + y 的級(jí)聯(lián)表達(dá)式
Function<Integer, Function<Integer, Integer>> function1 = x -> y -> x + y;
System.out.println("計(jì)算結(jié)果為: " + function1.apply(2).apply(3));  // 計(jì)算結(jié)果為: 5

這里的 y -> x + y 是作為一個(gè)函數(shù)返回給上一級(jí)表達(dá)式,所以第一級(jí)表達(dá)式的輸出是 y -> x + y這個(gè)函數(shù),如果使用括號(hào)括起來(lái)可能會(huì)好理解一些:

x -> (y -> x + y)

級(jí)聯(lián)表達(dá)式可以實(shí)現(xiàn)函數(shù)柯里化,簡(jiǎn)單來(lái)說(shuō)柯里化就是把本來(lái)多個(gè)參數(shù)的函數(shù)轉(zhuǎn)換為只有一個(gè)參數(shù)的函數(shù),如下示例:

Function<Integer, Function<Integer, Function<Integer, Integer>>> function2 = x -> y -> z -> x + y + z;
System.out.println("計(jì)算結(jié)果為: " + function2.apply(1).apply(2).apply(3));  // 計(jì)算結(jié)果為: 6

如果大家想學(xué)習(xí)以上路線內(nèi)容,在此我向大家推薦一個(gè)架構(gòu)學(xué)習(xí)交流群。交流學(xué)習(xí)群號(hào)874811168 里面會(huì)分享一些資深架構(gòu)師錄制的視頻錄像:有Spring,MyBatis,Netty源碼分析,高并發(fā)、高性能、分布式、微服務(wù)架構(gòu)的原理,JVM性能優(yōu)化、分布式架構(gòu)等這些成為架構(gòu)師必備的知識(shí)體系。還能領(lǐng)取免費(fèi)的學(xué)習(xí)資源,目前受益良多

函數(shù)柯里化的目的是將函數(shù)標(biāo)準(zhǔn)化,函數(shù)可靈活組合,方便統(tǒng)一處理等,例如我可以在循環(huán)里只需要調(diào)用同一個(gè)方法,而不需要調(diào)用另外的方法就能實(shí)現(xiàn)一個(gè)數(shù)組內(nèi)元素的求和計(jì)算,代碼如下:

public static void main(String[] args) {
    Function<Integer, Function<Integer, Function<Integer, Integer>>> f3 = x -> y -> z -> x + y + z;
    int[] nums = {1, 2, 3};
    for (int num : nums) {
        if (f3 instanceof Function) {
            Object obj = f3.apply(num);
            if (obj instanceof Function) {
                f3 = (Function) obj;
            } else {
                System.out.println("調(diào)用結(jié)束, 結(jié)果為: " + obj);  // 調(diào)用結(jié)束, 結(jié)果為: 6
            }
        }
    }
}

上述內(nèi)容就是怎么在Java中實(shí)現(xiàn)函數(shù)式編程,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI