自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

JDK新特性-Lambda表達(dá)式的神操作

開發(fā) 后端
Java8 引入 Lambda表達(dá)式是接收了函數(shù)式編程語言的思想,和指令式編程相比,函數(shù)式編程強(qiáng)調(diào)函數(shù)的計算比指令的執(zhí)行重要。引入 Lambda表達(dá)式是接收了函數(shù)式編程語言的思想,和指令式編程相比,函數(shù)式編程強(qiáng)調(diào)函數(shù)的計算比指令的執(zhí)行重要。

[[397312]]

一、Lambda表達(dá)式的介紹

  • Lambda表達(dá)式是 Java8 中最重要的新功能之一。使用 Lambda 表達(dá)式可以替代只有一個抽象函數(shù)的接口實現(xiàn),告別匿名內(nèi)部類,代碼看起來更簡潔易懂。Lambda表達(dá)式同時還提升了對集合、框架的迭代、遍歷、過濾數(shù)據(jù)的操作。
  • lambda表達(dá)式可以替代只有一個抽象函數(shù)的接口實現(xiàn),告別匿名內(nèi)部類,代碼看起來更簡潔易懂
  • lambda表達(dá)式同時還提升了對集合、框架的迭代、遍歷、過濾數(shù)據(jù)的操作
  • lambda可以極大的減少代碼冗余,同時代碼的可讀性要好過冗長的內(nèi)部類,匿名類

例如以前我們使用匿名內(nèi)部類來實現(xiàn)代碼:

  1. Runnable runnable = new Runnable() { 
  2.        @Override 
  3.        public void run() { 
  4.            System.out.println("running1 ....."); 
  5.        } 
  6.    }; 
  7.    runnable.run(); 

使用lambda表達(dá)式實現(xiàn)更簡潔的代碼:

  1. Runnable runnable3 = ()-> System.out.println("running2...."); 
  2.     runnable3.run(); 

lambda表達(dá)式語法:

  1. LambdaParameters -> LambdaBody 

 

在這里插入圖片描述

args -> expr或者(object … args)-> {函數(shù)式接口抽象方法實現(xiàn)邏輯}

1、()參數(shù)的個數(shù),根據(jù)函數(shù)式接口里面抽象的參數(shù)個數(shù)來決定,當(dāng)參數(shù)只有一個的時候,()可以省略

2、當(dāng)expr邏輯非常簡單的時候,{}和return可以省略

案例說明:

  1. public static void main(String[] args) throws Exception { 
  2.       Callable<String> c1 = new Callable() { 
  3.           @Override 
  4.           public String call() throws Exception { 
  5.               return "muxiaonong"
  6.           } 
  7.       }; 
  8.       System.out.println(c1.call()); 
  9.  
  10.       Callable<String> c2 = ()->{return "muxiaonong2";}; 
  11.       System.out.println(c2.call()); 
  12.  
  13.       //邏輯很簡單的時候省略 {} 和 return 
  14.       Callable<String> c3 = ()->"muxiaonong3"
  15.       System.out.println(c3.call()); 
  16.   } 

二、Lambda表達(dá)式的特點

  • 函數(shù)式編程
  • 參數(shù)類型自動推斷
  • 代碼量少,簡潔

三、Lambda表達(dá)式案例

實現(xiàn)方式列表:

  1. ()->{} 
  2.        ()->{System.out.println(1);} 
  3.        ()->System.out.println(1) 
  4.        ()->{return 100;} 
  5.        ()->100 
  6.        ()->null 
  7.        (int x)->{return x+1;} 
  8.        (int x)->x+1 
  9.        (x)->x+1 
  10.        x->x+1 

案例1:線程實現(xiàn)方式:

  1. public static void main(String[] args) { 
  2.       //匿名內(nèi)部類方式 
  3.       new Thread(new Runnable() { 
  4.           @Override 
  5.           public void run() { 
  6.               System.out.println("runing1.........."); 
  7.           } 
  8.       }); 
  9.  
  10.       //Lambda表達(dá)式方式 
  11.       new Thread(() -> {System.out.println("runing2.....");}).start(); 
  12.   } 

案例2:集合遍歷實現(xiàn)方式

  1. public static void main(String[] args) { 
  2.       List<String> list = Arrays.asList("java","python","scala","javascript"); 
  3.  
  4.       //普通匿名內(nèi)部類方式 
  5.       Collections.sort(list, new Comparator<String>() { 
  6.           @Override 
  7.           public int compare(String o1, String o2) { 
  8.               return o1.length() - o2.length(); 
  9.           } 
  10.       }); 
  11.  
  12.       //Lambda方式 
  13.       Collections.sort(list,(a,b) -> a.length() - b.length()); 
  14.       list.forEach(System.out::println); 
  15.   } 

四、Lambda表達(dá)式的應(yīng)用場景

重要的事情說三遍:任何有函數(shù)式接口的地方 * 3

什么是函數(shù)式接口: 只有一個抽象方法(Object類中的方法除外)的接口是函數(shù)式接口

五、Lambda表達(dá)式實際應(yīng)用

5.1 無參實體類模擬

模擬數(shù)據(jù)庫連接層:

  1. @FunctionalInterface 
  2. public interface StudentDao { 
  3.     void insert(Student student); 

實體類

  1. /** @Author mxn 
  2.  * @Description 學(xué)生實體類 
  3.  * @Date 10:19 2020/11/7 
  4.  * @Param  
  5.  * @return  
  6.  **/ 
  7. public class Student { 
  8.  public static void main(String[] args) { 
  9.         StudentDao sd1 = new StudentDao() { 
  10.             @Override 
  11.             public void insert(Student student) { 
  12.                 System.out.println("插入學(xué)生1"); 
  13.             } 
  14.         }; 
  15.  
  16.         StudentDao sd2 = (student)->{ 
  17.             System.out.println("student: "+student); 
  18.         }; 
  19.  
  20.         StudentDao sd3 = (Student student)-> System.out.println("student3:"+student); 
  21.  
  22.         sd1.insert(new Student()); //輸出 插入學(xué)生1 
  23.         sd2.insert(new Student());// 輸出 
  24.         sd3.insert(new Student());// 輸出 
  25.     } 

 5.2 有參實體類模擬

實體類

  1. /** @Author mxn 
  2.  * @Description  
  3.  * @Date 10:26 2020/11/7 
  4.  * @Param 
  5.  * @return 
  6.  **/ 
  7. public class Teacher { 

接口模擬層

  1. @FunctionalInterface 
  2. public interface TeacherDao { 
  3.     int get(Teacher teacher); 

實現(xiàn)層

  1.  public static void main(String[] args) { 
  2.         TeacherDao td1 = new TeacherDao() { 
  3.             @Override 
  4.             public int get(Teacher teacher) { 
  5.                 return 1; 
  6.             } 
  7.         }; 
  8.         TeacherDao td2 = (teacher)->{return 2;}; 
  9.         TeacherDao td3 = (Teacher teacher)->{return 3;}; 
  10.         TeacherDao td4 = (teacher)->4; 
  11.         TeacherDao td5 = (Teacher teacher)->5; 
  12.  
  13.         System.out.println(td1.get(new Teacher()));//輸出 1 
  14.         System.out.println(td2.get(new Teacher()));//輸出 2 
  15.         System.out.println(td3.get(new Teacher()));//輸出 3 
  16.         System.out.println(td4.get(new Teacher()));//輸出 4 
  17.         System.out.println(td5.get(new Teacher()));//輸出 5 

六、函數(shù)式接口

Supplier:代表一個輸出

Consumer:代表一個輸入

BiConsumer:代表兩個輸入

Function:代表一個輸入,一個輸出(一般輸入和輸出是不同類型的)

UnaryOperator:代表一個輸入,一個輸出(輸入和輸出是相同類型的)

BiFunction:代表兩個輸入,一個輸出(一般輸入和輸出是不同類型的)

BinaryOperator:代表兩個輸入,一個輸出(輸入和輸出是相同類型的)

在Java中提供了一系列的函數(shù)式接口,用來接受后續(xù)傳入的邏輯,但是對輸入和輸出有要求

6.1 Supplier:代表一個輸出

  1. Supplier<String> s1 = ()->{return "muxiaonong";}; 
  2.     Supplier<String> s2 = ()->"muxiaonong2"
  3.     System.out.println(s1.get());//輸出 muxiaonong 
  4.     System.out.println(s2.get());//輸出 muxiaonong2 

6.2 Consumer:代表一個輸入

  1. Consumer<String> c11 = (str) -> System.out.println(str); 
  2.    c11.accept("beijing");//輸出 beijing 

6.3 BiConsumer:代表兩個輸入

  1. BiFunction<String,String,Integer> bf = (a,b)->a.length()+b.length(); 
  2.      System.out.println(bf.apply("大吉大利""今晚吃雞"));//輸出一個字符串長度 8  

6.4 Function:代表一個輸入,一個輸出

  1. //  Function<String,Integer>  用來接收后面的函數(shù)的實現(xiàn),規(guī)定必須有一個輸入(String)有一個輸出(Integer
  2.  Function<String,Integer> f1 = (str)->{return str.length();}; 
  3.  System.out.println(f1.apply("abcdefg"));//輸出長度 7  

七、方法的引用

方法引用是用來直接訪問類或者實例的已經(jīng)存在的方法或者構(gòu)造方法,方法引用提供了一種引用而不執(zhí)行方法的方式,如果抽象方法的實現(xiàn)恰好可以使用調(diào)用另外一個方法來實現(xiàn),就有可能可以使用方法引用

7.1 方法引用的分類

7.2 靜態(tài)方法引用

靜態(tài)方法引用: 如果函數(shù)式接口的實現(xiàn)恰好可以通過 調(diào)用一個靜態(tài)方法 來實現(xiàn),那么就可以使用靜態(tài)方法引用

  1. /** 
  2.  * @program: lambda 
  3.  * @ClassName Test2 
  4.  * @description: 
  5.  * @author: muxiaonong 
  6.  * @create: 2020-10-28 22:15 
  7.  * @Version 1.0 
  8.  **/ 
  9. public class Test2 { 
  10.     //無參靜態(tài)方法 
  11.      static String put(){ 
  12.             System.out.println("put....."); 
  13.             return "put"
  14.         } 
  15.  
  16.     //有參靜態(tài)方法 
  17.     public static void getSize(int size){ 
  18.             System.out.println(size); 
  19.         } 
  20.  
  21.      //有參 有返回值靜態(tài)方法 
  22.      public static String toUpperCase(String str){ 
  23.             return str.toUpperCase(); 
  24.         } 
  25.  
  26.     //兩個入?yún)?,一個返回值靜態(tài)方法 
  27.     public static Integer getLength(String str,String str2){ 
  28.         return str.length()+str2.length(); 
  29.     } 
  30.  
  31.       public static void main(String[] args) { 
  32.         //無參靜態(tài)方法-普通調(diào)用 
  33.         System.out.println(put());//輸出put 
  34.         //無參靜態(tài)方法-原生調(diào)用 
  35.         Supplier<String> s1 = ()-> Test2.put(); 
  36.         System.out.println(s1.get());//輸出put 
  37.         //無參靜態(tài)方法-靜態(tài)方法引用 
  38.         Supplier<String> s2 = Test2::put; 
  39.         System.out.println(s2.get());//輸出put 
  40.         //無參靜態(tài)方法-內(nèi)部類調(diào)用 
  41.         Supplier<String> s3 = Fun::hehe; 
  42.         System.out.println(s3.get()); //輸出hehe 
  43.  
  44.         // 有參靜態(tài)方法-靜態(tài)方法引用 
  45.         Consumer<Integer> c1 = Test2::getSize; 
  46.         Consumer<Integer> c2 = (size)-> Test2.getSize(size); 
  47.         c1.accept(123); 
  48.         c2.accept(111); 
  49.  
  50.         //有參有返回值靜態(tài)方法 
  51.         Function<String,String> f1 = (str)->str.toUpperCase(); 
  52.         Function<String,String> f2 = (str)-> Test2.toUpperCase(str); 
  53.         Function<String,String> f3 = Test2::toUpperCase; 
  54.         Function<String,String> f4 = Test2::toUpperCase; 
  55.  
  56.         System.out.println(f1.apply("abc"));//輸出 ABC  
  57.         System.out.println(f2.apply("abc"));//輸出 ABC  
  58.         System.out.println(f3.apply("abc"));//輸出 ABC  
  59.         System.out.println(f4.apply("abc"));//輸出 ABC  
  60.  
  61.         // 兩個參數(shù) 一個返回值 函數(shù)式接口 
  62.          BiFunction<String,String,Integer> bf = (a, b)->a.length()+b.length(); 
  63.         BiFunction<String,String,Integer> bf2 = Test2::getLength; 
  64.         System.out.println(bf2.apply("abc""def"));//輸出 6 
  65.         System.out.println(bf.apply("abc""def"));//輸出 6 
  66.  
  67.     } 
  68.  
  69.     //內(nèi)部類 
  70.     class Fun { 
  71.         public static String hehe(){ 
  72.             return "hehe"
  73.         } 
  74.  
  75.         public static String toUpperCase(String str){ 
  76.             return str.toUpperCase(); 
  77.         } 
  78.  
  79.     } 
  80.  

7.3 實例方法引用

實例方法引用: 如果函數(shù)式接口的實現(xiàn)恰好可以通過調(diào)用一個實例的實例方法來實現(xiàn),那么就可以使用實例方法引用

  1. public class Test3 { 
  2.     //實例無參方法 
  3.     public String put(){ 
  4.         return "put..."
  5.     } 
  6.  
  7.     //實例有參方法 
  8.     public void getSize(int size){ 
  9.         System.out.println("size:"+size); 
  10.     } 
  11.  
  12.     //實例有參有返回值方法 
  13.     public String toUpperCase(String str){ 
  14.         return  str.toUpperCase(); 
  15.     } 
  16.     public static void main(String[] args) { 
  17.         //實例無參方法返回-普通調(diào)用 
  18.         System.out.println(new Test3().put());//輸出 put... 
  19.         Supplier<String> s1 = ()->new Test3().put(); 
  20.         Supplier<String> s2 = ()->{return new Test3().put();}; 
  21.         Supplier<String> s3 = new Test3()::put; 
  22.         System.out.println(s1.get());//輸出 put... 
  23.         System.out.println(s2.get());//輸出 put... 
  24.         System.out.println(s3.get());//輸出 put... 
  25.  
  26.         //唯一的創(chuàng)建一個test3對象 
  27.         Test3 test = new Test3(); 
  28.  
  29.         Consumer<Integer> c1 = (size)->new Test3().getSize(size); 
  30.         Consumer<Integer> c2 = new Test3()::getSize; 
  31.         Consumer<Integer> c3 = test::getSize; 
  32.  
  33.  
  34.         c1.accept(123);//輸出 size:123 
  35.         c2.accept(123);//輸出 size:123 
  36.         c3.accept(123);//輸出 size:123 
  37.  
  38.         Function<String,String> f1 = (str)->str.toUpperCase(); 
  39.         Function<String,String> f2 = (str)->test.toUpperCase(str); 
  40.         Function<String,String> f3 = new Test3()::toUpperCase; 
  41.         Function<String,String> f4 = test::toUpperCase; 
  42.         System.out.println(f1.apply("abc"));//輸出 ABC 
  43.         System.out.println(f2.apply("abc"));//輸出 ABC 
  44.         System.out.println(f3.apply("abc"));//輸出 ABC 
  45.         System.out.println(f4.apply("abc"));//輸出 ABC 
  46.     } 

7.4 對象方法引用

對象方法引用: 抽象方法的第一個參數(shù)類型剛好是實例方法的類型,抽象方法剩余的參數(shù)恰好可以當(dāng)做實例方法的參數(shù)。如果函數(shù)式接口的實現(xiàn)能由上面說的實例方法調(diào)用來實現(xiàn)的話,那么就可以使用對象方法引用

  1. /** @Author mxn 
  2.  * @Description //TODO 對象方法引用 
  3.  * @Date 14:26 2020/11/7 
  4.  * @Param  
  5.  * @return  
  6.  **/ 
  7. public class Test4 { 
  8.     public static void main(String[] args) { 
  9.         Consumer<Too> c1 = (too)->new Too().foo(); 
  10.         c1.accept(new Too());//輸出 foo 
  11.  
  12.         Consumer<Too> c2 = (Too too) ->new Too2().foo(); 
  13.         c2.accept(new Too());//輸出 foo---too2 
  14.  
  15.         Consumer<Too> c3 = Too::foo; 
  16.         c3.accept(new Too());//輸出 foo 
  17.  
  18.         BiConsumer<Too2,String> bc = (too2,str)->new Too2().show(str); 
  19.         BiConsumer<Too2,String> bc2 = Too2::show; 
  20.         bc.accept(new Too2(),"abc"); 
  21.         bc2.accept(new Too2(),"def"); 
  22.  
  23.         BiFunction<Exec,String,Integer> bf1 = (e,s)->new Exec().test(s); 
  24.         bf1.apply(new Exec(),"abc"); 
  25.         BiFunction<Exec,String,Integer> bf2 = Exec::test; 
  26.         bf2.apply(new Exec(),"def"); 
  27.     } 
  28.  
  29. class Exec
  30.     public int test(String name){ 
  31.         return 1; 
  32.     } 
  33.  
  34.  
  35. class Too{ 
  36.     public Integer fun(String s){ 
  37.         return 1; 
  38.     } 
  39.     public void foo(){ 
  40.         System.out.println("foo"); 
  41.     } 
  42. class Too2{ 
  43.     public Integer fun(String s){ 
  44.         return 1; 
  45.     } 
  46.     public void foo(){ 
  47.         System.out.println("foo---too2"); 
  48.     } 
  49.  
  50.     public void show(String str){ 
  51.         System.out.println("show ---too2"+str); 
  52.     } 

7.5 構(gòu)造方法引用

構(gòu)造方法引用: 如果函數(shù)式接口的實現(xiàn)恰好可以通過調(diào)用一個類的構(gòu)造方法來實現(xiàn),那么就可以使用構(gòu)造方法引用

  1. /** @Author mxn 
  2.  * @Description //TODO 構(gòu)造方法引用 
  3.  * @Date 14:27 2020/11/7 
  4.  * @Param  
  5.  * @return  
  6.  **/ 
  7. public class Test5 { 
  8.     public static void main(String[] args) { 
  9.         Supplier<Person> s1 = ()->new Person(); 
  10.         s1.get();//輸出 調(diào)用無參的構(gòu)造方法 
  11.         Supplier<Person> s2 = Person::new; 
  12.         s2.get();//輸出 調(diào)用無參的構(gòu)造方法 
  13.  
  14.         Supplier<List> s3 = ArrayList::new; 
  15.         Supplier<Set> s4 = HashSet::new; 
  16.         Supplier<Thread> s5 = Thread::new; 
  17.         Supplier<String> s6 = String::new; 
  18.  
  19.         Consumer<Integer> c1 = (age)->new Account(age); 
  20.         Consumer<Integer> c2 = Account::new; 
  21.         c1.accept(123);// 輸出 age 參數(shù)構(gòu)造123 
  22.         c2.accept(456);//輸出 age 參數(shù)構(gòu)造456 
  23.  
  24.         Function<String,Account> f1 = (str)->new Account(str); 
  25.         Function<String,Account> f2 = Account::new; 
  26.         f1.apply("abc");//輸出 str 參數(shù)構(gòu)造abc 
  27.         f2.apply("def");//輸出 str 參數(shù)構(gòu)造def 
  28.  
  29.     } 
  30.  
  31. class Account{ 
  32.     public Account(){ 
  33.         System.out.println("調(diào)用無參構(gòu)造方法"); 
  34.     } 
  35.  
  36.     public Account(int age){ 
  37.         System.out.println("age 參數(shù)構(gòu)造" +age); 
  38.     } 
  39.  
  40.     public Account(String str){ 
  41.         System.out.println("str 參數(shù)構(gòu)造" +str); 
  42.     } 
  43.  
  44. class Person{ 
  45.     public Person(){ 
  46.         System.out.println("調(diào)用無參的構(gòu)造方法"); 
  47.     } 

八、小結(jié)

  • Java8  引入 Lambda表達(dá)式是接收了函數(shù)式編程語言的思想,和指令式編程相比,函數(shù)式編程強(qiáng)調(diào)函數(shù)的計算比指令的執(zhí)行重要。引入 Lambda表達(dá)式是接收了函數(shù)式編程語言的思想,和指令式編程相比,函數(shù)式編程強(qiáng)調(diào)函數(shù)的計算比指令的執(zhí)行重要。引入 Lambda表達(dá)式是接收了函數(shù)式編程語言的思想,和指令式編程相比,函數(shù)式編程強(qiáng)調(diào)函數(shù)的計算比指令的執(zhí)行重要。
  • lambda表達(dá)式可以使代碼看起來簡潔,但一定程度上增加了代碼的可讀性以及調(diào)試的復(fù)雜性,所以在使用時應(yīng)盡量是團(tuán)隊都熟悉使用,要么干脆就別用,不然維護(hù)起來是件較痛苦的事,今天的小知識就到這里了,有問題的小伙伴可以在下方進(jìn)行留言,大家加油!

 

責(zé)任編輯:姜華 來源: 牧小農(nóng)
相關(guān)推薦

2023-12-28 08:00:40

lambda表達(dá)式Java 8

2009-08-10 10:06:10

.NET Lambda

2012-06-26 10:03:58

JavaJava 8lambda

2009-09-11 09:48:27

Linq Lambda

2009-09-09 13:01:33

LINQ Lambda

2009-09-15 15:18:00

Linq Lambda

2022-12-05 09:31:51

接口lambda表達(dá)式

2024-03-25 13:46:12

C#Lambda編程

2009-08-27 09:44:59

C# Lambda表達(dá)

2009-09-17 10:40:22

Linq Lambda

2009-09-15 17:30:00

Linq Lambda

2009-09-17 09:44:54

Linq Lambda

2021-11-10 09:45:06

Lambda表達(dá)式語言

2020-10-16 06:40:25

C++匿名函數(shù)

2009-07-09 09:51:07

Lambda表達(dá)式C#

2009-08-26 16:17:23

C# Lambda表達(dá)

2009-08-31 17:11:37

Lambda表達(dá)式

2009-08-27 09:57:50

C# Lambda表達(dá)

2009-09-17 09:09:50

Lambda表達(dá)式Linq查詢

2009-08-10 09:41:07

.NET Lambda
點贊
收藏

51CTO技術(shù)棧公眾號