成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

這個類庫可以幫助你理解Java中的函數式編程

開發 后端
今天介紹一個函數式Java工具包,它表現了很多優秀的函數式編程思想。以前介紹的熔斷降級組件Hystrix的替代品resilience4j就基于vavr庫。

[[405499]]

每當JDK發布了新版本就有同學說“你發任你發,我用Java 8”,可在工作中有不少人依然不太擅長使用Java8的新特性,而這些特性往往讓Java不再“臃腫”。不過我個人認為Java8所有的新特性中最具有代表性的一定是函數式編程。有人會說這種風格太抽象難懂了,當你熟練掌握這種設定之后,你一定會感到很香。慢慢地你也會領會到函數式編程的魅力和精髓。今天介紹一個函數式Java工具包,它表現了很多優秀的函數式編程思想。以前介紹的熔斷降級組件Hystrix的替代品resilience4j就基于vavr庫。

Vavr

Vavr是一個Java8函數庫,它運用了大量的函數式編程范式。創造性地封裝了一些持久性的數據結構和函數式控制結構。而且從中可以學到很多有用的編程思想。

可觀察的副作用

我們的代碼中經常會出現一些看不見的陷阱,從代碼語義中這些陷阱是無法被觀察的。例如

  1. int divide(int a, int b){ 
  2.  return a/b; 

我們知道a/b會得到一個整數,但是卻不能從代碼上明確地知道如果b=0將會拋出java.lang.ArithmeticException異常;而如果是a+b則不會帶來任何副作用。所以我們需要讓這種副作用是可觀察的。對于這一點Vavr做出了一種設計:

  1. Try<Integer> divide(Integer a, Integer b) { 
  2.     return Try.of(() -> a / b); 

將可能的副作用封裝到一個容器中,明確了可能的失敗,當你看到返回的是Try時,就意味著結果可能“并不順利”,以便于針對性地進行預防。

不可變的數據結構

很多語言都在使用不可變的數據結構,比如Golang、Kotlin。主要原因是不可變的值:

  • 本質上是線程安全的,因此不需要同步
  • 對于equals和hashCode是可靠的
  • 不需要克隆
  • 在非受檢unchecked類型轉換中是類型安全的
  • 對于函數式編程來說不可變值是最透明的

為此Vavr設計了一個集合類庫,旨在代替Java中的集合框架。Vavr 的集合庫包含一組豐富的函數式數據結構,這些數據結構建立在 lambdas 之上。它們與 Java 原始集合共享的唯一接口是Iterable。這些數據結構是持久性的,一旦初始化本身就不可改變,你可以使用一些操作來返回更改后的副本。例如經典的數據結構單向鏈表:

  1. // 1   2  3 
  2. List<Integer> source = List.of(1, 2, 3); 

如果我們將一個新元素0放在原始鏈表尾部的前面

  1. //  0  2  3 
  2. List<Integer> newHeadList = source.tail().prepend(0); 
  3. //  1  2  3 
  4. System.out.println(source); 

原始鏈表保持不變,新的鏈表大小保持不變元素被替換了。當然你可以使用其它API來生成一個大小變化的副本,不過可以肯定的是原始的鏈表一定不會發生改變。

  1. // 0 1 2 3 
  2. List<Integer> prepend = source.prepend(0); 
  3. // 1 2 3 0 
  4. List<Integer> append = source.append(0); 

這只是其中的一部分編程思想,接下來我將介紹Vavr的一些特色。

Vavr的一些特色

Vavr提供了一些非常有用的而且有特色的API。

元組

熟悉Python的同學對元組(Tuple)一定不陌生。元組將固定數量的元素組合在一起,以便它們可以作為一個整體傳遞。與數組或列表不同,元組可以包含不同類型的對象,但它也是不可變的。目前Vavr提供了最多8個元素的元組結構。

  1. // (felord.cn, 22) 
  2. Tuple2<String, Integer> java8 = Tuple.of("felord.cn", 22);  
  3. // felord.cn 
  4. String s = java8._1;  
  5. // 22 
  6. Integer i = java8._2; 

這個可以用來模擬Java中不具有的多返回值的特性。

Function

Java本身提供了Function接口,但是Vavr則提供了更加豐富的Function擴展,例如可以組合多個Function

  1. Function1<IntegerInteger> multiplyByTwo = a -> a * 2; 
  2. Function1<IntegerInteger> compose = multiplyByTwo.compose(a -> a + 1); 
  3. // 6 
  4. Integer apply = compose.apply(2); 

除此之外,還可以讓潛在的副作用降級(lift),有點類似于微服務的熔斷,以避免在函數執行中處理異常

  1. Function2<IntegerIntegerInteger> divide = (a, b) -> a / b; 
  2. // 降級  
  3. Function2<IntegerIntegerOption<Integer>> safeDivide = Function2.lift(divide); 
  4. // 返回一個加強版的Optional 
  5. Option<Integer> apply = safeDivide.apply(1, 0); 
  6. boolean empty = apply.isEmpty(); 
  7. // true 
  8. System.out.println(empty); 

還有派生操作:

  1. Function2<IntegerIntegerInteger> divide = (a, b) -> a / b; 
  2. Function1<IntegerInteger> a = divide.apply(4); 
  3. Integer apply = a.apply(2); 

這有點類似于柯里化,當我們用到更多入參時柯里化才更加明顯:

  1. Function3<IntegerIntegerIntegerIntegersum = (a, b, c) -> a + b + c; 
  2. final Function1<Integer, Function1<IntegerInteger>> add2 = sum.curried().apply(1); 
  3. Integer apply = add2.apply(2).apply(3); 

猜一猜答案是幾?

帶有特性的值容器

這個不太好用中文說明,有一些值帶有獨特的性質,比如開頭提到的Try,用來顯式表明可能遇到異常。Vavr提供了很多具有獨特性質的值容器。

Option

類似Optional,但是比Optional更加強大。

Lazy

Lazy是一個惰性計算的容器,表示當使用時才去計算且只計算一次。

  1. Lazy<Double> lazy = Lazy.of(Math::random); 
  2. lazy.isEvaluated(); // = false 
  3. lazy.get();         // = 0.123   
  4. lazy.isEvaluated(); // = true 
  5. lazy.get();         // = 0.123  
  6. // 需要使用數據時才從數據源加載 
  7. Data lazyData = Lazy.val(DataSourceService::get, Data.class); 

其它還有一些非常有用的容器,你可以嘗試它們。

模式匹配

函數式編程語言大都支持模式匹配,同為JVM語言的Scala中就有這種特性,而Java目前是沒有的。可以有效地幫助我們減少if-else,舉個例子:

  1. public static String convert(int input) { 
  2.  
  3.       String output
  4.       if (input == 1) { 
  5.           output = "one"
  6.       } else if (input == 2) { 
  7.           output = "two"
  8.       } else if (input == 3) { 
  9.           output = "three"
  10.       } else { 
  11.           output = "unknown"
  12.       } 
  13.       return output
  14.   } 

你就說吧,繞不繞?,Vavr就清爽多了。

  1. public static String vavrMatch(int input) { 
  2.      return Match(input).of
  3.              Case($(1), "one"), 
  4.              Case($(2), "two"), 
  5.              Case($(3), "three"), 
  6.              Case($(), "unknown"
  7.      ); 
  8.  } 

當然還有其它一些玩法需要你自己去發現。

總結

函數式編程作為Java8最大的一個亮點(個人認為),對于習慣于傳統OOP編程的開發者來說確實不容易接受。你不妨從Vavr類庫入手去學習函數式編程的思想。今天介紹的只是它很少的一部分,還有更多等著你去發現、去借鑒。忘記說了,如果你想在項目中引用它,可以引入下面這個坐標:

  1. <!-- https://mvnrepository.com/artifact/io.vavr/vavr --> 
  2. <dependency> 
  3.     <groupId>io.vavr</groupId> 
  4.     <artifactId>vavr</artifactId> 
  5.     <version>0.10.3</version> 
  6. </dependency> 

本文轉載自微信公眾號「 碼農小胖哥」,可以通過以下二維碼關注。轉載本文請聯系碼農小胖哥公眾號。

 

責任編輯:武曉燕 來源: 碼農小胖哥
相關推薦

2017-08-18 08:40:40

OpenStack建模數據中心

2024-09-29 15:35:23

2010-06-22 13:32:26

函數式編程JavaScript

2012-12-27 09:49:21

Web響應式

2020-02-06 19:12:36

Java函數式編程編程語言

2024-12-05 10:37:36

Java純函數final

2023-11-27 17:49:23

層次分析法算法

2022-10-08 14:26:09

開發Web工具

2010-08-03 08:54:07

JDK 7Lambda表達式函數式編程

2024-02-28 08:37:28

Lambda表達式Java函數式接口

2018-11-15 10:20:59

Python函數式編程編程語言

2023-10-07 00:01:02

Java函數

2023-02-19 15:20:19

2010-03-11 17:46:29

Pythond類

2019-06-18 07:15:22

Linux拼寫look命令

2020-09-23 07:50:45

Java函數式編程

2020-09-22 11:00:11

Java技術開發

2023-04-02 14:09:51

2017-10-17 16:23:58

函數式編程ReduxReact

2019-07-16 08:58:38

LinuxDocker軟件
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 麻豆精品国产91久久久久久 | 亚洲精品一区在线 | 午夜在线视频一区二区三区 | 国产女人精品视频 | 不卡欧美 | 国产99小视频 | 国产一区999 | 久久久久国色av免费观看性色 | 国产精品自拍啪啪 | 国产精品777一区二区 | 伊伊综合网 | 亚洲欧美日韩电影 | 日本三级日产三级国产三级 | 中国美女一级黄色片 | 武道仙尊动漫在线观看 | 亚洲成人99 | 免费看的黄网站 | 综合色在线 | 国产91久久久久 | 久久精品中文字幕 | 国产精品福利视频 | 在线日韩精品视频 | 日韩在线欧美 | 日韩在线观看一区 | 国产精品成人一区二区三区夜夜夜 | 精品一区二区在线观看 | 国产免费看 | 国产乡下妇女做爰 | 99re热精品视频 | 欧美精品一区二区三区在线四季 | 狠狠干天天干 | 国产一区在线免费观看 | 黄色网址在线免费播放 | 日本精品999 | 国产精品免费一区二区三区四区 | 老熟女毛片| 99精品99久久久久久宅男 | 视频在线一区二区 | 久久久999精品 | 91精品国产乱码久久久久久久久 | 在线一区二区三区 |