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

我們一起學習 WebFlux 前置知識

開發(fā) 架構
雖然 JDK8 發(fā)布距今已經(jīng)七八年了,但是相信還是有相當多小伙伴用著 JDK8,寫著 JDK6 的代碼。所以我們有必要回顧一下 JDK8,也算是我們學習 WebFlux 的一些前置知識。

 [[400435]]

最近太忙了,發(fā)文頻率有點不穩(wěn)定,理解萬歲。前面和大家說了要更 WebFlux,學習 WebFlux 之前,我們先來學習一些前置知識。

Rome was not built in a day。

WebFlux 也不是一幫人拍腦門突然發(fā)明的,它是一個漫長的過程,WebFlux 本身在逐步完善,各種配套工具/理論也在逐步發(fā)展。

因此當松哥想寫 WebFlux 的時候,發(fā)現(xiàn)沒法直接從 WebFlux 本身開始寫起,對于很多沒有接觸過函數(shù)式編程的人來說,上來就整 WebFlux 還是有一些挑戰(zhàn)的,想來想去,我覺得還是先來和大家捋一捋 JDK8 中的一些舊玩意。

雖然 JDK8 發(fā)布距今已經(jīng)七八年了,但是相信還是有相當多小伙伴用著 JDK8,寫著 JDK6 的代碼。所以我們有必要回顧一下 JDK8,也算是我們學習 WebFlux 的一些前置知識。

好啦,開整吧。

1.Lambda 表達式的四種寫法

JDK8 中引入了 Lambda,這個大家都知道,雖然現(xiàn)在 JDK 都出到 16 了,但是老實說,項目中的 Lambda 表達式似乎還是很少有人用。有的團隊技術風格激進,可能會見到很多 Lambda,但是大部分技術團隊還是比較保守的。今天為了學習 WebFlux,我們還是先來回顧一下 Lambda 表達式的幾種寫法。

先來說說,如果要用 Lambda,必須是只有一個需要強制實現(xiàn)方法的接口,我們可以使用 @FunctionalInterface 注解去標記該接口:

  1. @FunctionalInterface 
  2. interface ICalculator{ 
  3.     int square(int i); 

此時如果該接口中有多個空方法,編譯期間就會報錯。

現(xiàn)在我們建議盡量將一個接口設計的小一些,這樣也滿足單一職責原則。

不過 JDK8 中引入了 default 方法,就是自帶默認實現(xiàn)的那種,自帶默認實現(xiàn)的方法可以有多個,這個并不影響 Lambda,并且 @FunctionalInterface 注解也不會去檢查默認方法的數(shù)量。

1.1 單個參數(shù)的

如果只是一個參數(shù),那么直接寫參數(shù)即可,例如如下代碼:

  1. interface ICalculator{ 
  2.     int square(int i); 
  3. public class LambdaDemo01 { 
  4.     public static void main(String[] args) { 
  5.         ICalculator ic = i -> i * i; 
  6.         int square = ic.square(5); 
  7.         System.out.println("square = " + square); 
  8.     } 

當函數(shù)只有一個參數(shù)的時候,直接寫即可,不需要添加 ()。

1.2 多個參數(shù)

多個參數(shù)的話,就需要寫上 () 了,以 Spring Security 中登錄成功的回調(diào)為例(不了解 Spring Security 的小伙伴可在公號后臺回復 ss):

  1. .defaultLogoutSuccessHandlerFor((req,resp,auth)->{ 
  2.     resp.setContentType("application/json;charset=utf-8"); 
  3.     Map<String, Object> result = new HashMap<>(); 
  4.     result.put("status", 200); 
  5.     result.put("msg""使用 logout1 注銷成功!"); 
  6.     ObjectMapper om = new ObjectMapper(); 
  7.     String s = om.writeValueAsString(result); 
  8.     resp.getWriter().write(s); 
  9. },new AntPathRequestMatcher("/logout1","GET")) 
  10. .defaultLogoutSuccessHandlerFor((req,resp,auth)->{ 
  11.     resp.setContentType("application/json;charset=utf-8"); 
  12.     Map<String, Object> result = new HashMap<>(); 
  13.     result.put("status", 200); 
  14.     result.put("msg""使用 logout2 注銷成功!"); 
  15.     ObjectMapper om = new ObjectMapper(); 
  16.     String s = om.writeValueAsString(result); 
  17.     resp.getWriter().write(s); 
  18. },new AntPathRequestMatcher("/logout2","POST")) 
  19. .and() 
  20. .csrf().disable(); 

這種情況,方法有多個參數(shù),此時使用 Lambda 表達式就需要加上 ()。

1.3 要寫參數(shù)類型的

正常來說用 Lambda 時候不需要寫上參數(shù)類型,但是如果你需要寫,就要加上 (),還是上面那個例子,如下:

  1. interface ICalculator{ 
  2.     int square(int i); 
  3. public class LambdaDemo01 { 
  4.     public static void main(String[] args) { 
  5.         ICalculator ic = (int i) -> i * i; 
  6.         int square = ic.square(5); 
  7.         System.out.println("square = " + square); 
  8.     } 

1.4 方法體不止一行的

如果方法體不止一行,需要用上 {},如果方法體只有一行,則不需要 {},參考上面 2、3。

2.函數(shù)接口

JDK8 中自帶了函數(shù)式接口,使用起來也非常方便。

2.1基本應用

我們先來看一個簡單的例子。

假設我有一個打招呼的接口 SayHello,SayHello 接口中只有一個 sayHello 方法,然后在 User 類中調(diào)用該接口對應的方法,最終用法如下:

  1. @FunctionalInterface 
  2. interface SayHello { 
  3.     String sayHello(String name); 
  4.  
  5. class User { 
  6.     private String username; 
  7.  
  8.     public String getUsername() { 
  9.         return username; 
  10.     } 
  11.  
  12.     public void setUsername(String username) { 
  13.         this.username = username; 
  14.     } 
  15.  
  16.     public String say(SayHello sayHello) { 
  17.         return sayHello.sayHello(this.username); 
  18.     } 
  19.  
  20. public class LambdaDemo02 { 
  21.     public static void main(String[] args) { 
  22.         User user = new User(); 
  23.         user.setUsername("javaboy"); 
  24.         String say = user.say((username) -> "hello " + username); 
  25.         System.out.println("say = " + say); 
  26.     } 

分析 main 方法中的調(diào)用過程之后,我們發(fā)現(xiàn),在調(diào)用時最核心的是如下一行代碼:

  1. (username) -> "hello " + username 

在這段代碼中,我們只關心方法的輸入和輸出,其他的都不是我所考慮的,為了一個簡單的輸入輸出,我還要額外定義一個接口,這顯然不太劃算。

JDK8 中提供了函數(shù)接口,可以幫助我們簡化上面的接口定義。如下:

  1. class User2 { 
  2.     private String username; 
  3.  
  4.     public String getUsername() { 
  5.         return username; 
  6.     } 
  7.  
  8.     public void setUsername(String username) { 
  9.         this.username = username; 
  10.     } 
  11.  
  12.     public String say(Function<String,String> sayHello) { 
  13.         return sayHello.apply(this.username); 
  14.     } 
  15. public class LambdaDemo03 { 
  16.     public static void main(String[] args) { 
  17.         User2 user2 = new User2(); 
  18.         user2.setUsername("javaboy"); 
  19.         String say = user2.say((username) -> "hello " + username); 
  20.         System.out.println("say = " + say); 
  21.     } 

可以用 Function<String,String> 代替我們前面的接口定義,這里有兩個泛型,第一個泛型表示接口輸入的參數(shù)類型,第二個泛型表示接口輸出的參數(shù)類型,而且大家注意,我們最終 main 方法中的調(diào)用方式是不變的。有了 Function 函數(shù)之后,以后我們就不需要定義一些簡單的接口了。

而且 Function 函數(shù)還支持鏈式操作,如下:

  1. public class LambdaDemo03 { 
  2.     public static void main(String[] args) { 
  3.         User2 user2 = new User2(); 
  4.         user2.setUsername("javaboy"); 
  5.         Function<String, String> func = (username) -> "hello " + username; 
  6.         String say = user2.say(func.andThen(s -> "你好 " + s)); 
  7.         System.out.println("say = " + say); 
  8.     } 

2.2 其他函數(shù)接口

  1. 接口  輸入?yún)?shù)    返回類型    說明 
  2. UnaryOperator   T   T   一元函數(shù),輸入輸出類型相同 
  3. Predicate   T   boolean 斷言 
  4. Consumer    T   /   消費一個數(shù)據(jù),只有輸入沒有輸出 
  5. Function<T,R>   T   R   輸入 T 返回 R,有輸入也有輸出 
  6. Supplier    /   T   提供一個數(shù)據(jù),沒有輸入只有輸出 
  7. BiFunction<T,U,R>   (T,U)   R   兩個輸入?yún)?shù) 
  8. BiPredicate<L, R>   (L,R)   boolean 兩個輸入?yún)?shù) 
  9. BiConsumer<T, U>    (T,U)   void    兩個輸入?yún)?shù) 
  10. BinaryOperator  (T,T)   T   二元函數(shù),輸入輸出類型相同 

接下來我們來看看這些函數(shù)接口。

2.2.1 UnaryOperator

當輸入輸出類型相同時,可以使用 UnaryOperator 函數(shù)接口,例如我們上面的代碼,修改之后如下:

  1. class User2 { 
  2.     private String username; 
  3.  
  4.     public String getUsername() { 
  5.         return username; 
  6.     } 
  7.  
  8.     public void setUsername(String username) { 
  9.         this.username = username; 
  10.     } 
  11.  
  12.     public String say(UnaryOperator<String> sayHello) { 
  13.         return sayHello.apply(this.username); 
  14.     } 
  15. public class LambdaDemo03 { 
  16.     public static void main(String[] args) { 
  17.         User2 user2 = new User2(); 
  18.         user2.setUsername("javaboy"); 
  19.         UnaryOperator<String> func = (username) -> "helloo " + username; 
  20.         String say = user2.say(func); 
  21.         System.out.println("say = " + say); 
  22.     } 

2.2.2 Predicate

Predicate 輸入一個 T 類型的參數(shù),輸出一個 boolean 類型的值。

舉一個簡單的例子,例如如下代碼,我們定義一個 List 集合中存放著用戶姓名,現(xiàn)在要過濾出所有姓張的用戶,代碼如下:

  1. public class LambdaDemo04 { 
  2.     public static void main(String[] args) { 
  3.         List<String> names = Arrays.asList("張三""里斯""張五"); 
  4.         List<String> list = names.stream().filter(s -> s.startsWith("張")).collect(Collectors.toList()); 
  5.         for (String s : list) { 
  6.             System.out.println("s = " + s); 
  7.         } 
  8.     } 

filter 中傳入的就是一個 Predicate 函數(shù)接口,這個接口接收 String 類型的數(shù)據(jù),返回一個 boolean。

注意

一些常用類型的函數(shù)接口,JDK 中直接提供了相關的類供我們使用,例如 Predicate 可以用 IntPredicate 代替;Consumer 可以用 IntConsumer 代替。

2.2.3 Consumer

看名字就知道,這個是消費數(shù)據(jù),只有輸入沒有輸出。

例如集合的遍歷就可以使用 Consumer 函數(shù)接口。

  1. public class LambdaDemo04 { 
  2.     public static void main(String[] args) { 
  3.         List<String> names = Arrays.asList("張三""里斯""張五"); 
  4.         names.stream().forEach(s -> System.out.println(s)); 
  5.     } 

2.2.4 Supplier

Supplier 剛好和 Consumer 相反,它只有輸出沒有輸入。有的時候我們的工廠方法沒有輸入只有輸出,這個時候就可以考慮使用 Supplier(如果有輸入?yún)?shù),則可以考慮使用 Function 函數(shù)接口)。

  1. Supplier<Connection> supplier = ()->{ 
  2.     Connection con = null
  3.     try { 
  4.         con = DriverManager.getConnection(""""""); 
  5.     } catch (SQLException e) { 
  6.         e.printStackTrace(); 
  7.     } 
  8.     return con; 
  9. }; 
  10. Connection connection = supplier.get(); 

3.小結

其實 WebFlux 前置知識還是蠻多的,今天先聊這些吧,我們后面繼續(xù)。

本文轉(zhuǎn)載自微信公眾號「江南一點雨」,可以通過以下二維碼關注。轉(zhuǎn)載本文請聯(lián)系江南一點雨公眾號。

 

責任編輯:武曉燕 來源: 江南一點雨
相關推薦

2021-06-01 10:41:11

WebFlux 數(shù)據(jù)Backpressur

2022-02-14 10:16:22

Axios接口HTTP

2021-11-26 09:44:42

鏈表節(jié)點定位

2022-12-01 09:59:57

內(nèi)核觀測性方法

2021-05-20 07:15:34

RSA-PSS算法簽名

2023-03-28 07:32:37

2023-03-26 12:45:52

Linux內(nèi)核頭文件

2023-11-13 18:36:04

知識抽取NER

2021-10-11 10:25:33

排列nums數(shù)組

2021-03-18 00:04:13

C# 類型數(shù)據(jù)

2022-03-31 18:59:43

數(shù)據(jù)庫InnoDBMySQL

2023-08-10 08:28:46

網(wǎng)絡編程通信

2021-08-27 07:06:09

DubboDocker技術

2021-01-12 05:08:49

DHCP協(xié)議模型

2022-10-18 07:33:57

Maven構建工具

2023-08-04 08:20:56

DockerfileDocker工具

2023-06-30 08:18:51

敏捷開發(fā)模式

2022-05-24 08:21:16

數(shù)據(jù)安全API

2023-09-10 21:42:31

2024-02-20 21:34:16

循環(huán)GolangGo
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲综合资源 | 久久精品成人 | 成人精品一区二区三区中文字幕 | 91精品国产乱码久久久久久久久 | 国产色婷婷久久99精品91 | 在线视频亚洲 | 天天躁日日躁狠狠躁白人 | 欧美日本韩国一区二区三区 | 国产激情在线 | 99免费在线观看 | 国产高清在线观看 | 在线播放国产视频 | 中文字幕 国产 | 农村真人裸体丰满少妇毛片 | 欧美日韩精品综合 | 一区不卡在线观看 | 国产九九九九 | 四虎影音| 国产精品久久久久久久久久免费看 | 美日韩一区二区 | 一区二区三区视频播放 | 国产精品3区 | 久草新在线 | 综合久久久 | 国产精品一级在线观看 | 少妇一级淫片免费播放 | 岛国在线免费观看 | 一二三四av| 欧美日韩成人一区二区 | 伊人二区 | 欧美亚洲第一区 | 国产91网址 | 国产毛片久久久 | 韩日视频在线观看 | 少妇诱惑av | 欧美一级在线 | 日日噜噜噜夜夜爽爽狠狠视频, | 99精品视频在线 | 国产精品久久久久久久久久三级 | 亚洲男人天堂2024 | 免费国产视频 |