Jdk1.8新特性 - Lambda表達式

一、說明

    Jdk1.8最重要的特性即Lambda表達式。它允許把一個函數作爲參數傳遞進方法中,簡化了匿名實現類的書寫

    Lambda 表達式需要 函數式接口 的支持,即把只有一個抽象方法的接口的匿名實現,以方法參數在左,方法實現在右的形式構建,並將其作爲參數傳進方法中

    Lambda表達式引入了一個新的操作符 "->",它將Lambda分爲兩個部分:

	/**
	 * 左側:指定了Lambda表達式所需要的所有參數
	 * 右側:指定了Lambda表達式所要執行的代碼塊
	 */
	(參數類型 參數名, 參數類型 參數名...) -> { 
		代碼塊,即方法體
	};

二、示例

  •     1、線程
	// SE8 之前
	Thread thread = new Thread(new Runnable() {
		public void run() {
			System.out.println("hello world");
		}
	});
	thread.start();

	// SE8 開始
	Runnable runnable = () -> System.out.println("run ...");
	Thread thread = new Thread(runnable);
	thread.start();

	// SE8 簡寫
	new Thread(() -> System.out.println("run ...")).start();
  •     2、排序
	List<String> strs = new ArrayList<String>();

	// SE8 之前
	Collections.sort(strs, new Comparator<String>() {
		public int compare(String str1, String str2) {
			return str1.compareTo(str2);
		}
	});

	// SE8 開始
	Collections.sort(strs, (str1, str2) -> str1.compareTo(str2));
  •     3、自定義
	@FunctionalInterface
	public interface ExecInterface {
	
		public void execute(String a, String b);
		
	}

	// SE8之前
	ExecInterface execOri = new ExecInterface() {
		@Override
		public void execute(String a, String b) {
			System.out.println(a + b);
		}
	};
	execOri.execute("aaaa", "bbbb");

	// SE8開始
	ExecInterface execLam = (a, b) -> System.out.println(a + b);
	execLam.execute("aaaa", "bbbb");

三、語法

  •     1、完整語法
    // 函數式接口方法
    public void execute(String a, String b);
    
    // Lambda表達式   
    ExecInterface execLam = (String a, String b) -> {System.out.println(a + b);};
  •     2、參數類型可以省略 (類型推斷:因爲接口中只有一個抽象方法,知道方法即可推出參數及其類型)        
    // 函數式接口方法
    public void execute(String a, String b);
    // Lambda表達式
    ExecInterface execLam = ( a,  b) -> {System.out.println(a + b);};
  •     3、當參數個數只有一個時,也可以省略()
    //函數式接口方法
    public void execute(String a);

    //Lambda表達式
    ExecInterface execLam = a -> { System.out.println(a); };
  •     4、當方法體中只有一行代碼時,可以省略{}      
    //函數式接口方法
    public void execute(String a);
    
    //Lambda表達式
    ExecInterface execLam = a -> System.out.println(a);
  •      5、當方法體中只有一行代碼並且需要返回值時,也可以省略掉return       
    // 函數式接口方法
	public String execute(String a);
	
    // Lambda表達式
	ExecInterface execLam = a -> a + "hello";
  •        6、當表達式沒有參數時,一對小括號是不能省略掉的        
    // 函數式接口方法
	public void execute();
	
    // Lambda表達式
	ExecInterface execLam = () -> System.out.println("Hello");

四、常用

        Java8 內置了大量函數式接口,位於java.util.function包中,通常情況下不需要再自定義接口

  •     1、Supplier<T> :供應商;沒有參數,有返回值
	Supplier<String> supplier = () -> "Hello!";

	System.out.println(supplier.get());
  •     2、Consumer<T> :消費者;只有一個參數,沒有返回值
    Consumer<String> consumer = (name) -> System.out.println(name + ": " + "Hello!");
    
    consumer.accept("Xlien");
  •     3、Function<T, R> :函數;一個參數,一個返回值
    Function<String, String> func = (name) -> name + ": " + "Hello!"; 
    
    System.out.println(func.apply("Xlien"));
  •     4、BiFunction<T, U, R> :二元函數;兩個參數,一個返回值
    BiFunction<String, String, String> biFunc = (String name, String msg) -> {
        String str = name + "," + msg + "!";
        return str;
    };
    
    System.out.println(biFunc.apply("Xlien", "Hello!"));
  •     5、Comparator<T> :比較器;接收兩個參數,返回比較的結果
    Comparator<String> comparator = (s1, s2) -> s1.compareTo(s2);
    
    System.out.println(comparator.compare("abc", "abd"));
  •     6、Predicate<T> :斷言;用於測試一個條件的真假
    Predicate<String> predicate = (str) -> str.length() < 20; 
    // 即
    Predicate<String> predicate = new Predicate<String>() {
        @Override
        public boolean test(String str) {
            return str.length() < 20;
        }
    };
    
    System.out.println(predicate.test("[email protected]"));     // 判斷真假
    System.out.println(predicate.negate().test("[email protected]"));   // 邏輯否的判斷真假
    System.out.println(predicate.and((str) -> str.length() > 10).test("abcdefg"));   // 組合判斷 length<20 AND length > 10
    System.out.println(Predicate.isEqual("aaaa").test("aaaa"));   // 判斷是否相等(equal)

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章