程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 第二章 lambda表達式,lambda表達式

第二章 lambda表達式,lambda表達式

編輯:JAVA綜合教程

第二章 lambda表達式,lambda表達式


一、處理匿名內部類

1、Runnable接口

1         new Thread(new Runnable() {
2             public void run() {
3                 System.out.println("hello world!!!");
4             }
5         }).start();
6         
7         // lambda
8         new Thread(()->System.out.println("hello lambda!!!")).start();

說明:

  • 上邊的方式是原本匿名內部類方式
  • 下邊的方法是lambda表達式方式

lambda基本語法:(形參列表)->{方法體}

注意:

  • 形參列表:(String x, String y)這樣的基本形式
    • 如果沒有形參,使用"()",如上
    • 如果參數類型可以被推斷出來,使用(x,y)
    • 如果是單個參數且類型可以被推斷出來,直接使用x
  • 方法體:如果只有一句話,可以去掉"{}",如上

2、Comparator接口

 1         List<String> strList = Arrays.asList("zhaojigang","nana","tianya");
 2         //原來的方式
 3         Collections.sort(strList, new Comparator<String>() {
 4             @Override
 5             public int compare(String s1, String s2) {
 6                 return s1.compareTo(s2);
 7             }
 8         });
 9         
10         //lambda
11         Collections.sort(strList, (s1, s2)->s1.compareTo(s2));

說明:這裡的s1和s2就被根據comparator的泛型和strList的泛型推斷出了類型為String,可以省略參數類型。

二、方法引用

1         //lambda
2         Collections.sort(strList, (s1, s2)->s1.compareTo(s2));
3         //方法引用
4         Collections.sort(strList, String::compareTo);
5         //lambda
6         strList.forEach(x->System.out.println(x));
7         //方法引用
8         strList.forEach(System.out::println);

說明:

  • 前兩個語句效果一樣,後兩個效果一樣,自己比對方法引用與lambda的哪些部分等價
  • 集合類的foreach方法就是增強型for循環的再增強。

注意:

  • 方法引用的語法
    • 對象::實例方法=>等價於"提供方法參數的lambda表達式"
    • 類::靜態方法=>等價於"提供方法參數的lambda表達式"
      • eg. System.out::println等價於x->System.out.println(x)
    • 類::實例方法=>第一個參數是執行方法的對象
      • eg. String::compareTo等價於(s1, s2)->s1.compareTo(s2)

三、局部變量

lambda操作的局部變量必須是final型的,即:在lambda表達式所使用到的局部變量(方法體內的變量或形參)只能被讀取,不能被改變。

注意:列出這條約束的原因是防止線程不安全,可能會有疑問,局部變量是方法私有的,怎麼會有線程安全問題?

解釋:假設我在該方法體內,啟動了一個線程並使用lambda表達式去操作一個局部變量count(注意該變量並沒有在lambda中進行聲明,但是lambda卻可以用,這就是"閉包"),而在該線程外且在該方法體內,該方法也操作了count,這時可能就會有線程安全問題了。

四、接口的改變

java的接口也可以寫實現default級別的實例方法和靜態方法了。

 1 public interface LambdaInterface {
 2     //default方法
 3     default void defaultMethod(){
 4         System.out.println("xxxx");
 5     }
 6     //static方法
 7     static void staticMethod(){
 8         System.out.println("xxxx");
 9     }
10 }
1 public class TestInterface implements LambdaInterface{
2     public static void main(String[] args) {
3         LambdaInterface test = new TestInterface();
4         test.defaultMethod();//default方法測試
5         
6         LambdaInterface.staticMethod();//static方法測試
7     }
8 }

用途:當改造老的項目時,想在舊的接口中添加一些方法,但是又不想讓該接口的舊的實現類去實現這些方法時,可以使用這個技巧。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved