精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Java中的七種函數式編程技巧

開發 前端
在Java中限制數據變異的方法并不多。然而,通過使用純函數,并明確避免數據變異和重新賦值(使用我們之前討論過的其他概念),可以實現這一目標。對于變量,我們可以使用final關鍵字,它是一個非訪問修飾符,用于防止通過重新賦值來改變變量的值。

環境:Java21

1. 簡介

函數式編程是一種編程范式,以函數為核心,避免改變狀態與可變數據,強調函數的第一公民地位。它通過使用高階函數和純函數,實現代碼的模塊化和重用性,提升可讀性和可維護性,常用于并發編程和數學計算等領域。

在函數式編程中,有兩條非常重要的規則:

  • 無數據變異
    這意味著一旦數據對象被創建后就不應該再被更改。任何對該對象的操作都應該返回一個新的對象,而不是修改原始對象。
  • 無隱式狀態
    應避免隱藏或隱式狀態。這樣理解:在傳統編程中,一個函數可能依賴于一些外部或隱藏的狀態,比如全局變量、靜態變量或者類成員變量等,這些狀態不是通過參數傳遞給函數的。在函數式編程中,提倡避免這種隱式的依賴關系,而是將所有需要的狀態都作為參數顯式地傳遞給函數。這樣做的結果是提高了代碼的透明度和可測試性,因為你清楚地知道函數依賴哪些輸入來產生輸出,同時也減少了副作用的發生,即函數執行時除了返回值外不改變其他任何東西。

除了上述內容外,還有以下可以在Java中應用的函數式編程概念:

  • 高階函數(Higher-order functions)
  • 閉包(Closures)
  • 柯里化(Currying)
  • 遞歸(Recursion)
  • 惰性求值(Lazy evaluations)
  • 引用透明性(Referential transparency)

使用函數式編程并不意味著必須全盤采用,你可以始終使用函數式編程概念來補充面向對象的概念,尤其是在Java中。無論你使用的范式或語言是什么,都可以盡可能地利用函數式編程的優點。

接下來,我們將詳細介紹函數式編程在Java中的應用

2. 實戰案例

2.1 一等函數和高階函數

在一等函數的上下文中,函數被視為頭等公民,意味著它們可以被賦值給變量、作為參數傳遞給其他函數、從函數中返回,以及包含在數據結構中。遺憾的是,Java并不完全支持這一特性,因此像閉包、柯里化和高階函數這樣的概念在Java中實現起來不如在其他語言中那么方便。

在Java中最接近一等函數的概念是Lambda表達式。此外,在java.util.function包下還有一些內置的函數式接口,如Function、Consumer、Predicate、Supplier等,可以用于函數式編程。

只有當一個函數接受一個或多個函數作為參數,或者返回另一個函數作為結果時,它才能被視為高階函數。在Java中,我們最接近高階函數的方式是使用Lambda表達式和內置的函數式接口。

public class Test {
  public static void main(String[] args) {
    var list = Arrays.asList("Orange", "Apple", "Banana", "Grape", "XPack", "AKF");


    var ret = calcLength(list, new FnFactory<String, Object>() {
      public Object execute(final String it) {
        return it.length();
      }
    });
    System.err.printf("Length: %s%n", ret);
  }


  static <T, S> ArrayList<S> calcLength(List<T> arr, FnFactory<T, S> fn) {
    var list = new ArrayList<S>();
    arr.forEach(t -> list.add(fn.execute(t)));
    return list;
  }


  @FunctionalInterface
  public interface FnFactory<T, S> {
    S execute(T it);
  }

輸出結果:

Length: [6, 5, 6, 5, 5, 3]

接下來,我們使用內置的Function接口和Lambda表達式語法來簡化上面的示例:

public class Test1 {
  public static void main(String[] args) {
    var list = Arrays.asList("Orange", "Apple", "Banana", "Grape", "XPack", "AKF") ;
    var ret = calcLength(list, it -> it.length()) ;
    System.err.printf("Length: %s%n", ret) ;
  }


  static <T, S> ArrayList<S> calcLength(List<T> arr, Function<T, S> fn) {
    var list = new ArrayList<S>() ;
    arr.forEach(t -> list.add(fn.apply(t))) ;
    return list ;
  }
}

使用這些概念加上Lambda表達式,我們可以像下面這樣編寫閉包和柯里化。

public class ClosureTest {
  Function<Integer, Integer> add(final int x) {
    Function<Integer, Integer> add(final int x) {
    // 普通寫法
//    var partial = new Function<Integer, Integer>() {
//      public Integer apply(Integer y) {
//        return x + y;
//      }
//    };
    // 使用Lambda表達式語法;注意這里不能使用var
    Function<Integer, Integer> partial = y -> x + y ;
    return partial;
  }
    return partial;
  }


  public static void main(String[] args) {
    ClosureTest closure = new ClosureTest();


    var c1 = closure.add(100) ;
    var c2 = closure.add(200) ;


    System.out.println(c1.apply(66));
    System.out.println(c2.apply(66));
  }
}

運行結果

166
266

以上是關于閉包的應用。

Java中也有許多內置的高階函數,如java.util.Collections#sort方法:

public static void main(String[] args) {
  var list = Arrays.asList("Apple", "Orange", "Banana", "Grape");


  Collections.sort(list, (String a, String b) -> {
    return a.compareTo(b);
  });


  System.err.printf("%s%n", list) ; 
}

Java Stream相關API中也提供了許多高階函數,比如forEach、map等。

2.2 純函數

函數式編程傾向于使用遞歸而不是循環。在Java中,這可以通過使用流API或編寫遞歸函數來實現。讓我們來看一個計算數字階乘的例子。還使用JMH對這些方法進行了基準測試,并在下方列出了每操作的納秒數。

在傳統的迭代方法中:

@State(Scope.Thread)
public class FactorialTest {
  // 我們要使用JMH進行測試,所以通過@Param定義入參
  @Param({"20"})
  private long num ;
  @Benchmark
  public long factorial() {
    long result = 1;
    for (; num > 0; num--) {
      result *= num;
    }
    return result;
  }


  public static void main(String[] args) throws Exception {
    Options options = new OptionsBuilder()
        .include(FactorialTest.class.getSimpleName())
        .forks(1)
        .build() ;
    new Runner(options).run() ;
  }
}

測試結果

Benchmark                (num)  Mode  Cnt  Score   Error  Units
FactorialTest.factorial     20  avgt    5  0.475 ± 0.013  ns/op

同樣的功能也可以使用遞歸來實現,如下所示,這在函數式編程中更為青睞。

@State(Scope.Thread)
public class FactorialTest2 {
  @Param({ "20" })
  private long num;


  @Benchmark
  public long factorialRec() {
    return factorial(num);
  }
  private long factorial(long n) {
    return n == 1 ? 1 : n * factorial(n - 1);
  }
  public static void main(String[] args) throws Exception {
    Options options = new OptionsBuilder()
        .include(FactorialTest2.class.getSimpleName())
        .forks(1)
        .build();
    new Runner(options).run();
  }
}

測試結果

Benchmark                    (num)  Mode  Cnt   Score   Error  Units
FactorialTest2.factorialRec     20  avgt    5  17.316 ± 0.792  ns/op

遞歸方法的缺點是,它通常會比迭代方法更慢(我們追求的優勢在于代碼的簡潔性和可讀性),并且由于每次函數調用都需要作為棧幀保存到堆棧中,可能會導致棧溢出錯誤。

我們還可以使用Stream進行遞歸調用

@Param({ "20" })
private long num;


@Benchmark
public long factorialRec() {
  return LongStream.rangeClosed(1, num)
      .reduce(1, (n1, n2) -> n1 * n2);
}

運行結果

Benchmark                    (num)  Mode  Cnt   Score   Error  Units
FactorialTest2.factorialRec     20  avgt    5  17.618 ± 1.414  ns/op

與遞歸算法差不多。

在編寫Java代碼時,考慮到可讀性和不可變性,可以考慮使用流API或遞歸;但如果性能至關重要,或者迭代次數將非常大,則應使用標準循環。

2.3 惰性求值(Lazy evaluations)

惰性求值(Lazy evaluation)或非嚴格求值是指推遲表達式的計算,直到其結果真正被需要時才進行計算。一般來說,Java執行的是嚴格求值,但對于像&&、||和?:這樣的運算符,它會進行惰性求值。我們可以利用這一點在編寫Java代碼時實現惰性求值。

考慮下面這個例子,在這個例子中Java會急切地(eagerly)計算所有內容:

public static void main(String[] args) {
  System.out.println(addOrMultiply(true, add(4), multiply(4))); // 8
  System.out.println(addOrMultiply(false, add(4), multiply(4))); // 16
}


public static int add(int x) {
  System.out.println("executing add");
  return x + x;
}


public static int multiply(int x) {
  System.out.println("executing multiply");
  return x * x;
}


public static int addOrMultiply(boolean add, int onAdd, int onMultiply) {
  return (add) ? onAdd : onMultiply;
}

執行結果

executing add
executing multiply
8
executing add
executing multiply
16

函數一早就被執行了。

我們可以使用Lambda表達式和高階函數將此重寫為惰性求值的版本:

public static void main(String[] args) {
  UnaryOperator<Integer> add = t -> {
    System.out.println("executing add");
    return t + t;
  };
  UnaryOperator<Integer> multiply = t -> {
    System.out.println("executing multiply");
    return t * t;
  };
  System.out.println(addOrMultiply(true, add, multiply, 4));
  System.out.println(addOrMultiply(false, add, multiply, 4));
}


public static <T, R> R addOrMultiply(
    boolean add, Function<T, R> onAdd, 
    Function<T, R> onMultiply, T t) {
  return (add ? onAdd.apply(t) : onMultiply.apply(t));
}

執行結果

executing add
8
executing multiply
16

我們可以看到只執行了所需的功能。

2.4 引用透明性(Referential transparency)

表示在程序中,一個函數調用可以用它的返回值來替換,而不改變程序的行為。換句話說,對于相同的輸入,函數總是產生相同的結果,沒有副作用。

遺憾的是,在Java中限制數據變異的方法并不多。然而,通過使用純函數,并明確避免數據變異和重新賦值(使用我們之前討論過的其他概念),可以實現這一目標。對于變量,我們可以使用final關鍵字,它是一個非訪問修飾符,用于防止通過重新賦值來改變變量的值。

例如,下面的代碼將在編譯時產生錯誤:

final var list = Arrays.asList("Apple", "Orange") ;
// 你不能重新賦值
list = Arrays.asList("Pack", "XXXOOO") ;

但是,當變量持有對其他對象的引用時,這并不會起到作用。例如,即使使用了final關鍵字,下面的對象變異仍然會發生:

final var list = new ArrayList<>() ;
// 我們還是可以添加數據
list.add("XXX") ;
list.add("OOO") ;

final 關鍵字允許引用變量的內部狀態被修改,因此從函數式編程的角度來看,final 關鍵字僅對常量和捕獲重新賦值有用。

責任編輯:武曉燕 來源: Spring全家桶實戰案例源碼
相關推薦

2021-10-19 14:51:33

說服力IT主管CIO

2011-02-22 16:09:53

Eclipse調試

2022-07-01 08:00:44

異步編程FutureTask

2015-09-02 12:12:13

2019-11-11 16:44:20

機器學習Python算法

2025-08-05 08:30:08

2025-05-13 08:20:58

2013-01-07 10:14:06

JavaJava枚舉

2020-01-14 08:00:00

.NET緩存編程語言

2022-05-10 08:08:01

find命令Linux

2025-02-10 08:43:31

Java異步編程

2022-03-14 07:40:14

RibbonSpringNacos

2022-07-25 10:15:29

垃圾收集器Java虛擬機

2025-01-21 08:00:00

限流微服務算法

2010-10-15 10:02:01

Mysql表類型

2025-05-12 10:00:00

JavaScript代碼編碼

2016-03-16 10:39:30

數據分析數據科學可視化

2023-02-14 08:32:41

Ribbon負載均衡

2019-09-06 09:00:00

開發技能代碼

2025-01-15 10:46:23

開發JavaScript集合
點贊
收藏

51CTO技術棧公眾號

精品污污网站免费看| 国产一区二区三区香蕉| 亚洲欧美中文日韩在线| 在线看的黄色网址| av片在线观看免费| 99久久99久久精品国产片果冻 | 精品无人国产偷自产在线| 国产超碰在线播放| 欧美家庭影院| 国产网站一区二区| av资源一区二区| 波多野结衣绝顶大高潮| 狠狠88综合久久久久综合网| 国产一区二区美女视频| 亚洲最大视频网| 日韩中文在线播放| 亚洲国产欧美日韩另类综合 | av电影高清在线观看| 91日韩一区二区三区| 91免费视频国产| 波多野结衣电车| 中文日韩在线| 欧美激情久久久| 国精品人伦一区二区三区蜜桃| 久久国产精品免费精品3p| 91精品国产美女浴室洗澡无遮挡| 成人羞羞国产免费网站| 久久香蕉一区| 亚洲男人天堂av| 亚洲乱码一区二区三区 | 2020日本不卡一区二区视频| av一区观看| 国产美女主播在线观看| 免费成人在线视频观看| 五月婷婷激情综合网| 伊人精品在线观看| 91传媒理伦片在线观看| 欧美精品影院| 制服丝袜在线91| 亚洲一区在线不卡| 久久久一本精品| 岛国av一区二区三区| 日本精品久久久久久久久久| 在线看女人毛片| 亚洲麻豆国产自偷在线| 无码人妻精品一区二区三区99v| 在线观看国产原创自拍视频| 欧美激情自拍偷拍| 视频二区一区| www免费网站在线观看| 久久久久国产精品人| 欧美成人一区二区在线| 欧美理论在线观看| 国产亚洲精品7777| 日本在线视频一区| 国产在线观看网站| 国产日产欧美一区| 日韩欧美一区二区在线观看 | 在线免费看av片| 日本不卡高清视频| 国产欧美精品va在线观看| 亚洲天天综合网| 国内精品视频一区二区三区八戒| 91九色综合久久| 国产成人麻豆精品午夜在线| 国产一区二区三区四区五区美女| 91网站免费看| 午夜精品在线播放| a亚洲天堂av| 久久亚洲午夜电影| 成人免费在线视频网| 中文字幕一区免费在线观看| 在线观看视频黄色| 黑人精品视频| 日韩欧美精品免费在线| 国产嫩草在线观看| 澳门黄色一级片| 妖精视频一区二区三区| 一区二区亚洲欧洲国产日韩| 性生交大片免费全黄| 欧美喷水视频| 欧洲一区二区视频| 91九色蝌蚪91por成人| 国产精品一级二级三级| 国产伦精品一区二区| 三级在线视频| 国产精品久久久久影视| a级黄色片免费| 亚洲欧美se| 777精品伊人久久久久大香线蕉| 亚洲美女精品视频| 国产精品三级| 九九热精品视频国产| 日本中文字幕在线| 国产在线视视频有精品| 精品一区久久久久久| 午夜不卡视频| 五月天亚洲婷婷| 日韩高清第一页| 国产精品xxx在线观看| 亚洲天天在线日亚洲洲精| 中文字幕人妻一区二| 亚洲中字黄色| 91国产丝袜在线放| 第一视频专区在线| 亚洲777理论| 亚洲精品成人在线播放| 宅男在线一区| 欧美精品videossex88| 91theporn国产在线观看| 91一区一区三区| 路边理发店露脸熟妇泻火| 欧美人体一区二区三区| 精品久久久久久久久久久久包黑料 | 国产极品在线播放| 久久精品国产免费看久久精品| 精品国产乱码久久久久久88av| 午夜视频在线免费观看| 精品久久中文字幕| 亚洲人精品午夜在线观看| 日本护士做爰视频| 国精品一区二区三区| 国产精品一区二区久久| 欧美zozo| 婷婷一区二区三区| 三上悠亚 电影| 欧美电影《轻佻寡妇》| 国产精品99久久久久久人| 欧美 日韩 国产 成人 在线 91| 综合网在线视频| youjizzxxxx18| 蜜桃一区二区| 欧美在线观看网址综合| 天天干天天做天天操| 亚洲午夜免费视频| 免费国偷自产拍精品视频| 日韩黄色大片网站| 国产精品免费视频久久久| 免费看男男www网站入口在线| 午夜不卡av免费| 天堂www中文在线资源| 黄色综合网站| 国产传媒欧美日韩| gogo高清在线播放免费| 精品少妇一区二区三区日产乱码| 亚洲色图综合区| 国产一区二区三区四区在线观看| 日本a级片在线观看| 久久久精品区| 欧美日韩国产成人在线| 亚洲精品字幕在线| 亚洲成人一区在线| 污污内射在线观看一区二区少妇| 亚洲国产一区二区精品专区| 国产自产精品| 依依综合在线| 亚洲一区二区久久久| 日本视频www色| 国产精品乱人伦| 黄色a级三级三级三级| 欧美aⅴ99久久黑人专区| 99精品在线直播| 波多野结衣久久| 精品香蕉在线观看视频一| 亚洲av无码精品一区二区| 国产日产精品一区| 中文字幕在线观看日| 99视频精品全国免费| 91在线看www| 韩国成人免费视频| 日韩精品视频在线| 探花国产精品一区二区| 亚洲人成网站色在线观看| 中国特级黄色片| 国产精品久久久亚洲一区| 日韩欧美手机在线| 久久久久毛片免费观看| 97碰碰碰免费色视频| 国产在线你懂得| 欧美一区中文字幕| 日韩精品手机在线| 欧美国产精品劲爆| 佐佐木明希电影| 石原莉奈一区二区三区在线观看| 一区二区精品免费视频| 国产一区福利| 国产精品视频xxx| 黄网av在线| 中文字幕av一区中文字幕天堂 | 久久久久成人片免费观看蜜芽| av不卡在线播放| 天天干天天操天天做| 精品1区2区3区4区| 亚洲精品一卡二卡三卡四卡| 大型av综合网站| 国产精品久久久久久影视 | 一区二区三区网站| 狼狼综合久久久久综合网| 亚洲成a人片777777久久| 2019中文字幕免费视频| 制服丝袜中文字幕在线| 一区二区三区四区精品| 后进极品白嫩翘臀在线视频| 欧美日韩一区二区三区在线| 中国一级免费毛片| 亚洲精品免费电影| 九一在线免费观看| 99国产精品99久久久久久| 欧美激情第一区| 巨乳诱惑日韩免费av| 草草视频在线免费观看| 91精品啪在线观看国产18| 你懂的视频在线一区二区| 1204国产成人精品视频| 国产女人18毛片水18精品| 欧美黑人一区| 欧美亚洲第一区| 成人性生交大片免费看网站 | 欧美韩国亚洲| 69av成年福利视频| 福利在线导航136| 欧美成人一区二区三区电影| 尤物网在线观看| 亚洲欧美国内爽妇网| 手机在线观看毛片| 欧美大片一区二区三区| 国产乱淫av免费| 欧美系列亚洲系列| 波多野结衣一区二区三区在线 | 精品国产av鲁一鲁一区| 欧美日本高清视频在线观看| 无码视频一区二区三区| 色婷婷综合在线| 亚洲免费黄色网址| 都市激情亚洲色图| 日韩无码精品一区二区三区| 亚洲国产日韩综合久久精品| 久久久国产精品黄毛片| 一区二区三区色| 久久精品一级片| 亚洲综合在线视频| 久久97人妻无码一区二区三区| ...xxx性欧美| 婷婷在线精品视频| 一区二区三区在线观看网站| 校园春色 亚洲| 一区二区三区中文字幕精品精品| 538任你躁在线精品视频网站| 自拍av一区二区三区| 高h视频免费观看| 亚洲在线中文字幕| 日韩污视频在线观看| 色婷婷狠狠综合| 亚洲 小说区 图片区| 欧美日韩精品欧美日韩精品一综合| 曰批又黄又爽免费视频| 欧美日产国产精品| a天堂在线视频| 亚洲国产精品人人爽夜夜爽| 久久电影中文字幕| 中文在线不卡视频| 操你啦在线视频| 久久久久亚洲精品| 在线观看欧美日韩电影| 国产原创欧美精品| 免费精品一区二区三区在线观看| 99国精产品一二二线| 亚洲素人在线| 一本久久a久久精品vr综合| 中文不卡在线| 日日橹狠狠爱欧美超碰| 日本中文字幕一区二区有限公司| 三级一区二区三区| 99视频精品在线| wwwww黄色| 一区二区三区中文字幕精品精品 | 国产三区精品| 欧美日韩久久精品| 日本一道在线观看| 首页亚洲欧美制服丝腿| 特级黄色片视频| 99久久婷婷国产综合精品电影| 最新中文字幕av| 一区二区三区四区av| 亚洲精品久久久久久久蜜桃| 日韩一区二区视频| 亚洲欧洲综合在线| 理论片在线不卡免费观看| 日韩脚交footjobhdboots| 国产免费成人av| 台湾色综合娱乐中文网| 手机看片日韩国产| 国产精品视频| 一级片黄色免费| 久久九九99视频| 久久免费黄色网址| 欧美日韩一二三区| 少妇性bbb搡bbb爽爽爽欧美| 欧美成人激情视频| 最新日韩三级| 久久国产精品一区二区三区四区| 久久精品久久久| 男人插女人下面免费视频| av网站免费线看精品| av激情在线观看| 欧美午夜精品一区二区三区 | 午夜日韩影院| 日韩精品在在线一区二区中文| 狠狠干成人综合网| 777一区二区| 国产日韩精品视频一区| 精品成人av一区二区在线播放| 欧美刺激脚交jootjob| 在线免费观看的av网站| 日韩av免费在线播放| 卡通动漫国产精品| 777久久精品一区二区三区无码 | 影音先锋在线播放| 国产精品尤物福利片在线观看| 亚洲精品动态| 青青青免费在线| 高清在线不卡av| 中文字幕亚洲欧美日韩| 欧美剧情电影在线观看完整版免费励志电影| 天堂资源中文在线| 国外成人在线直播| 成人av婷婷| av无码久久久久久不卡网站| 国产成人精品免费网站| 欧美另类videoxo高潮| 欧美日韩大陆一区二区| 在线观看免费网站黄| 国产欧美精品xxxx另类| 日韩欧美一区二区三区免费看| 性chinese极品按摩| 欧美国产日韩a欧美在线观看| 国产suv精品一区二区33| 亚洲免费成人av电影| 成人线上视频| 欧美精品七区| 久久午夜精品| 婷婷色一区二区三区| 欧美午夜免费电影| 91电影在线播放| 国产中文字幕亚洲| 91精品一区二区三区综合| 九九热免费在线观看| 综合分类小说区另类春色亚洲小说欧美| 中文字幕久久网| 久久精品成人欧美大片古装| av在线播放一区二区| 欧美日韩午夜爽爽| 成人综合婷婷国产精品久久蜜臀| 国产无套内射又大又猛又粗又爽| 亚洲国产欧美一区| 久九九久频精品短视频| 日韩福利视频| 精品夜夜嗨av一区二区三区| 成年人一级黄色片| 精品美女被调教视频大全网站| 草草视频在线| 欧美美乳视频网站在线观看| 日本欧洲一区二区| 懂色av懂色av粉嫩av| 欧美精品一区二区蜜臀亚洲| 在线免费三级电影网站| 日本在线观看一区| 国内一区二区视频| 国产成人亚洲精品自产在线| 亚洲人成免费电影| 亚洲一区av| 分分操这里只有精品| 久久久国产精品麻豆| 91theporn国产在线观看| 久久久久久成人| 成人羞羞网站入口免费| 成人在线短视频| 婷婷中文字幕综合| 在线观看免费高清完整| 国产日韩欧美亚洲一区| 日本在线不卡视频一二三区| 中文字幕av免费在线观看| 日韩精品在线观看一区二区| 99re8精品视频在线观看| 亚洲美免无码中文字幕在线 | 国产大片中文字幕在线观看| 亚洲男人第一网站| 秋霞影院一区| 欧美日韩在线不卡视频| 亚洲欧洲性图库| 色婷婷激情五月| 国产欧美久久一区二区| 99成人在线| 少妇aaaaa| 一区二区三区 在线观看视| 天堂精品久久久久| 97超碰成人在线| 色婷婷精品久久二区二区蜜臀av | 亚洲午夜久久久久久久久电影网| 成人在线观看免费|