<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
Java Lambda表示式是JDK8引入的,是一個比較重要的特性
Lambda 表示式是 JDK8 的一個新特性,也被稱為閉包,Lambda表示式允許把函數作為一個方法的引數,即行為引數化,函數作為引數傳遞進方法中。
Lambda表示式可以取代大部分的匿名內部類,寫出更優雅的 Java 程式碼,尤其在集合的遍歷和其他集合操作中,可以極大地優化程式碼結構。
Java 8 引入的 Lambda表示式的主要作用就是簡化程式碼,寫出更優雅的程式碼。
怎麼一個簡化優雅呢,舉一Lambda語法建立執行緒和匿名內部類建立執行緒的例子,就非常清楚了。
// JDK7匿名內部類寫法 new Thread(new Runnable() {//介面名 @Override public void run() {//方法名 System.out.println("mikechen"); } });
// JDK8 Lambda來建立執行緒 new Thread(() -> System.out.println("mikechen"));
上述程式碼跟匿名內部類的作用是一樣的,但比匿名內部類更進一步,這裡連介面名和函數名都一同省掉了,Lambda表示式可以取代匿名內部類,寫出更優雅的程式碼。
lambda 表示式的語法格式如下:
Lambda體只有一條語句:
範例:
() -> System.out.println("mikechen");
請注意,括號中沒有內容。那就是表示lambda不帶任何引數。
範例:
Consumer<String> con = (x) -> System.out.println(x);
當lambda表示式是單個引數時,也可以省略括號,如下所示:
Consumer<String> con = x -> System.out.println(x);
如果Java lambda表示式匹配的方法有多個引數,則需要在括號內列出這些引數,程式碼如下:
BinaryOperator<Integer> bo = (a, b) -> { System.out.println("函數式介面"); return a + b; };
注意:僅當方法是單個引數時,才可以省略括號。
如果編譯器無法從lambda匹配的函數式介面抽象方法推斷引數型別,則有時可能需要為lambda表示式指定引數型別。
(Car car) -> System.out.println("The car is: " + car.getName());
如你所見,car引數的型別(Car)寫在引數名稱的前面,就像在其他方法中宣告引數或對介面進行匿名實現時一樣。
當Lambda體只有一條語句時,return和大括號可以省略,範例:
BinaryOperator<Integer> bo = (a, b) -> a + b;
Lambda表示式的參數列的資料型別可以省略不寫,因為JVM編譯器能夠通過上下文推斷出資料型別,這就是“型別推斷”,範例:
BinaryOperator<Integer> bo = (Integer a, Integer b) -> { return a + b; };
等同於
BinaryOperator<Integer> bo = (a, b) -> { return a + b; };
上述 Lambda 表示式中的引數型別都是由編譯器推斷得出,Lambda 表示式中無需指定型別,程式依然可以編譯,這是因為 javac 根據程式的上下文,在後臺推斷出了引數的型別。
Lambda 表示式的型別依賴於上下文環境,是由編譯器推斷出來的,這就是所謂的“型別推斷”。
你可以從Java lambda表示式返回值,就像從方法中返回值一樣。你只需向lambda表示式主體新增一個return,如下所示:
(param) -> { System.out.println("param: " + param); return "return value"; }
Lambda表示式需要函數式介面的支援,所以,我們有必要來說說什麼是函數式介面。
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface FunctionalInterface {}
一種用於表示一個介面是Java語言規範定義的函數式介面的註解型別。
對於函數式介面,我們可以理解為只有一個抽象方法的介面,除此之外它和別的介面相比並沒有什麼特殊的地方。
public interface MyFunctionInterface<T> { public T getValue(T t); }
為了確保函數式介面的正確性,我們可以給這個介面新增@FunctionalInterface註解,這樣當其中有超過一個抽象方法時就會報錯。
Unexpected @FunctionalInterface annotation @FunctionalInterface ^ WorkerInterface is not a functional interface multiple non-overriding abstract methods found in interface WorkerInterface 1 error
Java 8中每一個Lambda表示式必須有一個函數式介面與之對應,也就是說,只要一個物件是函數式介面的範例,那麼該物件就可以用Lambda表示式來表示。
學習 Lambda 表示式的最好方式是學習例子,下面我們看幾個比較常用的例子。
使用() -> {} 替代匿名類:
//JDK 8之前 new Thread(new Runnable() { @Override public void run() { System.out.println("使用匿名內部類,開執行緒"); } }).start(); //JDK 8 使用lambda表示式 new Thread(() -> System.out.println("使用lambda表示式,開執行緒")).start();
使用lambda表示式如下所示寫出更好的事件偵聽器的程式碼:
// Java 8之前: button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("Button被點選了使用老的方式!"); } }); // Java 8方式: button.addActionListener( (e) -> { System.out.println("Button被點選了使用Lambda表示式!"); });
集合的遍歷,採用lambda表示式會更簡潔:
// Java 8之前: List features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API"); for (String feature : features) { System.out.println(feature); } // Java 8之後: List features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API"); features.forEach(n -> System.out.println(n)); // 使用Java 8的方法參照更方便,方法參照由::雙冒號操作符標示, features.forEach(System.out::println);
方法參照是使用兩個冒號::這個操作符號。
之前我們若要為集合內的元素排序,就必須呼叫 sort 方法,傳入比較器重寫 compare。
方法的比較器物件,現在我們還可以使用 lambda 表示式來簡化程式碼。
public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("a"); list.add("d"); list.add("b"); list.add("c"); list.sort((o1,o2)->o1.compareTo(o2)); list.forEach(System.out::println); }
// 不使用lambda表示式為每個訂單加上12%的稅 List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500); for (Integer cost : costBeforeTax) { double price = cost + .12*cost; System.out.println(price); } // 使用lambda表示式 List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500); costBeforeTax.stream().map((cost) -> cost + .12*cost).forEach(System.out::println);
// 建立一個字串列表,每個字串長度大於2 List<String> filtered = strList.stream().filter(x -> x.length()> 2).collect(Collectors.toList()); System.out.printf("Original List : %s, filtered list : %s %n", strList, filtered);
// 將字串換成大寫並用逗號連結起來 List<String> G7 = Arrays.asList("USA", "Japan", "France", "Germany", "Italy", "U.K.","Canada"); String G7Countries = G7.stream().map(x -> x.toUpperCase()).collect(Collectors.joining(", ")); System.out.println(G7Countries);
//獲取數位的個數、最小值、最大值、總和以及平均值 List<Integer> primes = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29); IntSummaryStatistics stats = primes.stream().mapToInt((x) -> x).summaryStatistics(); System.out.println("Highest prime number in List : " + stats.getMax()); System.out.println("Lowest prime number in List : " + stats.getMin()); System.out.println("Sum of all prime numbers : " + stats.getSum()); System.out.println("Average of all prime numbers : " + stats.getAverage());
以上就是Java Lambda表示式詳解的詳細內容,更多關於Java Lambda表示式詳解的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45