您好,登錄后才能下訂單哦!
這篇文章主要介紹“JDK中Lambda表達式的操作”,在日常操作中,相信很多人在JDK中Lambda表達式的操作問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”JDK中Lambda表達式的操作”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
Lambda表達式是 Java8 中最重要的新功能之一。使用 Lambda 表達式可以替代只有一個抽象函數的接口實現,告別匿名內部類,代碼看起來更簡潔易懂。Lambda表達式同時還提升了對集合、框架的迭代、遍歷、過濾數據的操作。
lambda表達式可以替代只有一個抽象函數的接口實現,告別匿名內部類,代碼看起來更簡潔易懂
lambda表達式同時還提升了對集合、框架的迭代、遍歷、過濾數據的操作
lambda可以極大的減少代碼冗余,同時代碼的可讀性要好過冗長的內部類,匿名類
例如以前我們使用匿名內部類來實現代碼:
Runnable runnable = new Runnable() { @Override public void run() { System.out.println("running1 ....."); } }; runnable.run();
使用lambda表達式實現更簡潔的代碼:
Runnable runnable3 = ()-> System.out.println("running2...."); runnable3.run();
lambda表達式語法:
LambdaParameters -> LambdaBody
在這里插入圖片描述
args -> expr或者(object … args)-> {函數式接口抽象方法實現邏輯}
1、()參數的個數,根據函數式接口里面抽象的參數個數來決定,當參數只有一個的時候,()可以省略
2、當expr邏輯非常簡單的時候,{}和return可以省略
案例說明:
public static void main(String[] args) throws Exception { Callable<String> c1 = new Callable() { @Override public String call() throws Exception { return "muxiaonong"; } }; System.out.println(c1.call()); Callable<String> c2 = ()->{return "muxiaonong2";}; System.out.println(c2.call()); //邏輯很簡單的時候省略 {} 和 return Callable<String> c3 = ()->"muxiaonong3"; System.out.println(c3.call()); }
函數式編程
參數類型自動推斷
代碼量少,簡潔
實現方式列表:
()->{} ()->{System.out.println(1);} ()->System.out.println(1) ()->{return 100;} ()->100 ()->null (int x)->{return x+1;} (int x)->x+1 (x)->x+1 x->x+1
案例1:線程實現方式:
public static void main(String[] args) { //匿名內部類方式 new Thread(new Runnable() { @Override public void run() { System.out.println("runing1.........."); } }); //Lambda表達式方式 new Thread(() -> {System.out.println("runing2.....");}).start(); }
案例2:集合遍歷實現方式
public static void main(String[] args) { List<String> list = Arrays.asList("java","python","scala","javascript"); //普通匿名內部類方式 Collections.sort(list, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.length() - o2.length(); } }); //Lambda方式 Collections.sort(list,(a,b) -> a.length() - b.length()); list.forEach(System.out::println); }
重要的事情說三遍:任何有函數式接口的地方 * 3
什么是函數式接口: 只有一個抽象方法(Object類中的方法除外)的接口是函數式接口
5.1 無參實體類模擬
模擬數據庫連接層:
@FunctionalInterface public interface StudentDao { void insert(Student student); }
實體類
/** @Author mxn * @Description 學生實體類 * @Date 10:19 2020/11/7 * @Param * @return **/ public class Student { } public static void main(String[] args) { StudentDao sd1 = new StudentDao() { @Override public void insert(Student student) { System.out.println("插入學生1"); } }; StudentDao sd2 = (student)->{ System.out.println("student: "+student); }; StudentDao sd3 = (Student student)-> System.out.println("student3:"+student); sd1.insert(new Student()); //輸出 插入學生1 sd2.insert(new Student());// 輸出 sd3.insert(new Student());// 輸出 }
5.2 有參實體類模擬
實體類
/** @Author mxn * @Description * @Date 10:26 2020/11/7 * @Param * @return **/ public class Teacher { }
接口模擬層
@FunctionalInterface public interface TeacherDao { int get(Teacher teacher); }
實現層
public static void main(String[] args) { TeacherDao td1 = new TeacherDao() { @Override public int get(Teacher teacher) { return 1; } }; TeacherDao td2 = (teacher)->{return 2;}; TeacherDao td3 = (Teacher teacher)->{return 3;}; TeacherDao td4 = (teacher)->4; TeacherDao td5 = (Teacher teacher)->5; System.out.println(td1.get(new Teacher()));//輸出 1 System.out.println(td2.get(new Teacher()));//輸出 2 System.out.println(td3.get(new Teacher()));//輸出 3 System.out.println(td4.get(new Teacher()));//輸出 4 System.out.println(td5.get(new Teacher()));//輸出 5 }
Supplier:代表一個輸出
Consumer:代表一個輸入
BiConsumer:代表兩個輸入
Function:代表一個輸入,一個輸出(一般輸入和輸出是不同類型的)
UnaryOperator:代表一個輸入,一個輸出(輸入和輸出是相同類型的)
BiFunction:代表兩個輸入,一個輸出(一般輸入和輸出是不同類型的)
BinaryOperator:代表兩個輸入,一個輸出(輸入和輸出是相同類型的)
在Java中提供了一系列的函數式接口,用來接受后續傳入的邏輯,但是對輸入和輸出有要求
6.1 Supplier:代表一個輸出
Supplier<String> s1 = ()->{return "muxiaonong";}; Supplier<String> s2 = ()->"muxiaonong2"; System.out.println(s1.get());//輸出 muxiaonong System.out.println(s2.get());//輸出 muxiaonong2
6.2 Consumer:代表一個輸入
Consumer<String> c11 = (str) -> System.out.println(str); c11.accept("beijing");//輸出 beijing
6.3 BiConsumer:代表兩個輸入
BiFunction<String,String,Integer> bf = (a,b)->a.length()+b.length(); System.out.println(bf.apply("大吉大利", "今晚吃雞"));//輸出一個字符串長度 8
6.4 Function:代表一個輸入,一個輸出
// Function<String,Integer> 用來接收后面的函數的實現,規定必須有一個輸入(String)有一個輸出(Integer) Function<String,Integer> f1 = (str)->{return str.length();}; System.out.println(f1.apply("abcdefg"));//輸出長度 7
方法引用是用來直接訪問類或者實例的已經存在的方法或者構造方法,方法引用提供了一種引用而不執行方法的方式,如果抽象方法的實現恰好可以使用調用另外一個方法來實現,就有可能可以使用方法引用
7.1 方法引用的分類
7.2 靜態方法引用
靜態方法引用: 如果函數式接口的實現恰好可以通過 調用一個靜態方法 來實現,那么就可以使用靜態方法引用
/** * @program: lambda * @ClassName Test2 * @description: * @author: muxiaonong * @create: 2020-10-28 22:15 * @Version 1.0 **/ public class Test2 { //無參靜態方法 static String put(){ System.out.println("put....."); return "put"; } //有參靜態方法 public static void getSize(int size){ System.out.println(size); } //有參 有返回值靜態方法 public static String toUpperCase(String str){ return str.toUpperCase(); } //兩個入參,一個返回值靜態方法 public static Integer getLength(String str,String str2){ return str.length()+str2.length(); } public static void main(String[] args) { //無參靜態方法-普通調用 System.out.println(put());//輸出put //無參靜態方法-原生調用 Supplier<String> s1 = ()-> Test2.put(); System.out.println(s1.get());//輸出put //無參靜態方法-靜態方法引用 Supplier<String> s2 = Test2::put; System.out.println(s2.get());//輸出put //無參靜態方法-內部類調用 Supplier<String> s3 = Fun::hehe; System.out.println(s3.get()); //輸出hehe // 有參靜態方法-靜態方法引用 Consumer<Integer> c1 = Test2::getSize; Consumer<Integer> c2 = (size)-> Test2.getSize(size); c1.accept(123); c2.accept(111); //有參有返回值靜態方法 Function<String,String> f1 = (str)->str.toUpperCase(); Function<String,String> f2 = (str)-> Test2.toUpperCase(str); Function<String,String> f3 = Test2::toUpperCase; Function<String,String> f4 = Test2::toUpperCase; System.out.println(f1.apply("abc"));//輸出 ABC System.out.println(f2.apply("abc"));//輸出 ABC System.out.println(f3.apply("abc"));//輸出 ABC System.out.println(f4.apply("abc"));//輸出 ABC // 兩個參數 一個返回值 函數式接口 BiFunction<String,String,Integer> bf = (a, b)->a.length()+b.length(); BiFunction<String,String,Integer> bf2 = Test2::getLength; System.out.println(bf2.apply("abc", "def"));//輸出 6 System.out.println(bf.apply("abc", "def"));//輸出 6 } //內部類 class Fun { public static String hehe(){ return "hehe"; } public static String toUpperCase(String str){ return str.toUpperCase(); } } }
7.3 實例方法引用
實例方法引用: 如果函數式接口的實現恰好可以通過調用一個實例的實例方法來實現,那么就可以使用實例方法引用
public class Test3 { //實例無參方法 public String put(){ return "put..."; } //實例有參方法 public void getSize(int size){ System.out.println("size:"+size); } //實例有參有返回值方法 public String toUpperCase(String str){ return str.toUpperCase(); } public static void main(String[] args) { //實例無參方法返回-普通調用 System.out.println(new Test3().put());//輸出 put... Supplier<String> s1 = ()->new Test3().put(); Supplier<String> s2 = ()->{return new Test3().put();}; Supplier<String> s3 = new Test3()::put; System.out.println(s1.get());//輸出 put... System.out.println(s2.get());//輸出 put... System.out.println(s3.get());//輸出 put... //唯一的創建一個test3對象 Test3 test = new Test3(); Consumer<Integer> c1 = (size)->new Test3().getSize(size); Consumer<Integer> c2 = new Test3()::getSize; Consumer<Integer> c3 = test::getSize; c1.accept(123);//輸出 size:123 c2.accept(123);//輸出 size:123 c3.accept(123);//輸出 size:123 Function<String,String> f1 = (str)->str.toUpperCase(); Function<String,String> f2 = (str)->test.toUpperCase(str); Function<String,String> f3 = new Test3()::toUpperCase; Function<String,String> f4 = test::toUpperCase; System.out.println(f1.apply("abc"));//輸出 ABC System.out.println(f2.apply("abc"));//輸出 ABC System.out.println(f3.apply("abc"));//輸出 ABC System.out.println(f4.apply("abc"));//輸出 ABC } }
7.4 對象方法引用
對象方法引用: 抽象方法的第一個參數類型剛好是實例方法的類型,抽象方法剩余的參數恰好可以當做實例方法的參數。如果函數式接口的實現能由上面說的實例方法調用來實現的話,那么就可以使用對象方法引用
/** @Author mxn * @Description //TODO 對象方法引用 * @Date 14:26 2020/11/7 * @Param * @return **/ public class Test4 { public static void main(String[] args) { Consumer<Too> c1 = (too)->new Too().foo(); c1.accept(new Too());//輸出 foo Consumer<Too> c2 = (Too too) ->new Too2().foo(); c2.accept(new Too());//輸出 foo---too2 Consumer<Too> c3 = Too::foo; c3.accept(new Too());//輸出 foo BiConsumer<Too2,String> bc = (too2,str)->new Too2().show(str); BiConsumer<Too2,String> bc2 = Too2::show; bc.accept(new Too2(),"abc"); bc2.accept(new Too2(),"def"); BiFunction<Exec,String,Integer> bf1 = (e,s)->new Exec().test(s); bf1.apply(new Exec(),"abc"); BiFunction<Exec,String,Integer> bf2 = Exec::test; bf2.apply(new Exec(),"def"); } } class Exec{ public int test(String name){ return 1; } } class Too{ public Integer fun(String s){ return 1; } public void foo(){ System.out.println("foo"); } } class Too2{ public Integer fun(String s){ return 1; } public void foo(){ System.out.println("foo---too2"); } public void show(String str){ System.out.println("show ---too2"+str); } }
7.5 構造方法引用
構造方法引用: 如果函數式接口的實現恰好可以通過調用一個類的構造方法來實現,那么就可以使用構造方法引用
/** @Author mxn * @Description //TODO 構造方法引用 * @Date 14:27 2020/11/7 * @Param * @return **/ public class Test5 { public static void main(String[] args) { Supplier<Person> s1 = ()->new Person(); s1.get();//輸出 調用無參的構造方法 Supplier<Person> s2 = Person::new; s2.get();//輸出 調用無參的構造方法 Supplier<List> s3 = ArrayList::new; Supplier<Set> s4 = HashSet::new; Supplier<Thread> s5 = Thread::new; Supplier<String> s6 = String::new; Consumer<Integer> c1 = (age)->new Account(age); Consumer<Integer> c2 = Account::new; c1.accept(123);// 輸出 age 參數構造123 c2.accept(456);//輸出 age 參數構造456 Function<String,Account> f1 = (str)->new Account(str); Function<String,Account> f2 = Account::new; f1.apply("abc");//輸出 str 參數構造abc f2.apply("def");//輸出 str 參數構造def } } class Account{ public Account(){ System.out.println("調用無參構造方法"); } public Account(int age){ System.out.println("age 參數構造" +age); } public Account(String str){ System.out.println("str 參數構造" +str); } } class Person{ public Person(){ System.out.println("調用無參的構造方法"); } }
到此,關于“JDK中Lambda表達式的操作”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。