91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

WebFlux 前置知識有哪些

發布時間:2021-06-22 13:53:19 來源:億速云 閱讀:220 作者:chen 欄目:開發技術

這篇文章主要介紹“ WebFlux 前置知識有哪些”,在日常操作中,相信很多人在 WebFlux 前置知識有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答” WebFlux 前置知識有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

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

Rome was not built in a day。

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

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

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

好啦,開整吧。

1.Lambda 表達式的四種寫法

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

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

@FunctionalInterface interface ICalculator{     int square(int i); }

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

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

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

1.1 單個參數的

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

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

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

1.2 多個參數

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

.defaultLogoutSuccessHandlerFor((req,resp,auth)->{     resp.setContentType("application/json;charset=utf-8");     Map<String, Object> result = new HashMap<>();     result.put("status", 200);     result.put("msg", "使用 logout1 注銷成功!");     ObjectMapper om = new ObjectMapper();     String s = om.writeValueAsString(result);     resp.getWriter().write(s); },new AntPathRequestMatcher("/logout1","GET")) .defaultLogoutSuccessHandlerFor((req,resp,auth)->{     resp.setContentType("application/json;charset=utf-8");     Map<String, Object> result = new HashMap<>();     result.put("status", 200);     result.put("msg", "使用 logout2 注銷成功!");     ObjectMapper om = new ObjectMapper();     String s = om.writeValueAsString(result);     resp.getWriter().write(s); },new AntPathRequestMatcher("/logout2","POST")) .and() .csrf().disable();

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

1.3 要寫參數類型的

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

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

1.4 方法體不止一行的

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

2.函數接口

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

2.1基本應用

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

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

@FunctionalInterface interface SayHello {     String sayHello(String name); }  class User {     private String username;      public String getUsername() {         return username;     }      public void setUsername(String username) {         this.username = username;     }      public String say(SayHello sayHello) {         return sayHello.sayHello(this.username);     } }  public class LambdaDemo02 {     public static void main(String[] args) {         User user = new User();         user.setUsername("javaboy");         String say = user.say((username) -> "hello " + username);         System.out.println("say = " + say);     } }

分析 main 方法中的調用過程之后,我們發現,在調用時最核心的是如下一行代碼:

(username) -> "hello " + username

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

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

class User2 {     private String username;      public String getUsername() {         return username;     }      public void setUsername(String username) {         this.username = username;     }      public String say(Function<String,String> sayHello) {         return sayHello.apply(this.username);     } } public class LambdaDemo03 {     public static void main(String[] args) {         User2 user2 = new User2();         user2.setUsername("javaboy");         String say = user2.say((username) -> "hello " + username);         System.out.println("say = " + say);     } }

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

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

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

2.2 其他函數接口

接口  輸入參數    返回類型    說明 UnaryOperator   T   T   一元函數,輸入輸出類型相同 Predicate   T   boolean 斷言 Consumer    T   /   消費一個數據,只有輸入沒有輸出 Function<T,R>   T   R   輸入 T 返回 R,有輸入也有輸出 Supplier    /   T   提供一個數據,沒有輸入只有輸出 BiFunction<T,U,R>   (T,U)   R   兩個輸入參數 BiPredicate<L, R>   (L,R)   boolean 兩個輸入參數 BiConsumer<T, U>    (T,U)   void    兩個輸入參數 BinaryOperator  (T,T)   T   二元函數,輸入輸出類型相同

接下來我們來看看這些函數接口。

2.2.1 UnaryOperator

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

class User2 {     private String username;      public String getUsername() {         return username;     }      public void setUsername(String username) {         this.username = username;     }      public String say(UnaryOperator<String> sayHello) {         return sayHello.apply(this.username);     } } public class LambdaDemo03 {     public static void main(String[] args) {         User2 user2 = new User2();         user2.setUsername("javaboy");         UnaryOperator<String> func = (username) -> "helloo " + username;         String say = user2.say(func);         System.out.println("say = " + say);     } }

2.2.2 Predicate

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

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

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

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

注意

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

2.2.3 Consumer

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

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

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

2.2.4 Supplier

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

Supplier<Connection> supplier = ()->{     Connection con = null;     try {         con = DriverManager.getConnection("", "", "");     } catch (SQLException e) {         e.printStackTrace();     }     return con; }; Connection connection = supplier.get();

到此,關于“ WebFlux 前置知識有哪些”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

安远县| 滨海县| 彭山县| 肥城市| 自治县| 娄烦县| 迭部县| 长宁区| 桃园市| 贞丰县| 天等县| 壶关县| 炎陵县| 扎赉特旗| 丰都县| 上高县| 务川| 鹿邑县| 英德市| 横山县| 霸州市| 浙江省| 神农架林区| 定结县| 博湖县| 陇西县| 图木舒克市| 普洱| 松潘县| 泾源县| 红桥区| 灵台县| 墨竹工卡县| 明水县| 扬州市| 吉隆县| 竹溪县| 松桃| 邵阳县| 英吉沙县| 东源县|