1. 程式人生 > >java1.8新特性-lambda表示式

java1.8新特性-lambda表示式

  • 什麼是lambda表示式

長期以來,java為了保持簡單性和一致性,拒絕給變數賦值成“一段程式碼”,如果你想把“一段程式碼”賦給一個Java變數,應該怎麼做呢?這個“一段程式碼”就是lambda表示式。

  • 為什麼引入lambda表示式

lambo表示式是一個可傳遞的程式碼塊,具體介紹語法之前,先來看看我們在java中的哪些地方用過這種程式碼塊。比如:

public static void main(String[] args) {
   String[] planets = new String[] {  "宋大寶", "大瀋陽", "張三瘋子", "騰", "夏洛特", "趙四","劉小能" };
		Arrays.sort(planets, new Comparator<String>() {

			@Override
			public int compare(String first, String second) {
				return first.length() - second.length();
			}
		});

		System.out.println(Arrays.toString(planets));
  
    }

這段程式碼大家應該很熟悉,是用sort方法傳入一個Comparator物件進行list排序。

這其中有一個特點是構造出Comparator物件,compare包含一段程式碼來完成對“一段程式碼”的傳遞。

到目前為止,在java中傳遞一個程式碼段並不容易,不能直接傳遞程式碼段。java是一種面嚮物件語言,所以必須構造一個物件。這個物件的類需要有一個方法能包含所需的程式碼。

  • lambda表示式的語法

再來考慮上面討論排序的例子。我們傳入程式碼來檢查一個字串是否比另一個字串短。這裡要計算:

first.length() - second.length()

first和second是什麼?他們都是字串。java是一種強型別語言,所以我們還要指定它們的型別:

(String first, String second)
    -> first.length() - second.length()

這就是你看到的第一個lambda表示式。lambda表示式就是一個程式碼塊,以及必須傳入程式碼的變數規範。

至此,我們可以看出lambda表示式形式:

(引數) -> 一個表示式或一段程式碼

如果想傳入的程式碼很多無法放在一個表示式中,就可以像寫方法一樣,把這些程式碼放在{}中,幷包含顯示的return語句。例如:

(String first, String second) ->
{
    if(first.length() < second.length()) return -1;
    else if(first.length() > second.length()) return 1;
    else return 0;
}

如果沒有引數怎麼辦?仍然要提供空括號,就像無引數方法一樣:

() -> { for(int i = 100; i>=0; i++) System.out.println(i); }

如果可以推匯出一個lambda表示式的引數型別,則可以忽略其型別。例如:

Comparator<String> comp = (first, second) -> first.length - second.length;

在這裡,編譯器可以推匯出first和second必然是字串。因為lambda表示式將賦給一個字串比較器。

如果方法只有一個引數,而且這個引數的型別可以推導得出。那麼甚至還可以省略小括號:

Timer t = new Timer(1000, event -> 
			System.out.println("The time is:" + new Date()));

例項程式碼:

package com.lambda;

import java.util.Arrays;
import java.util.Date;

import javax.swing.JOptionPane;
import javax.swing.Timer;

public class LambdaTest {

	public static void main(String[] args) {
		String[] planets = new String[] { "宋大寶", "大瀋陽", "張三瘋子", "騰", "夏洛特", "趙四", "劉小能" };
		System.out.println(Arrays.toString(planets));
		System.out.println("排序:");
		Arrays.sort(planets);
		System.out.println(Arrays.toString(planets));
		System.out.println("根據長度排序:");
		Arrays.sort(planets, (first, second) -> first.length() - second.length());
		System.out.println(Arrays.toString(planets));

		Timer t = new Timer(1000, event -> 
			System.out.println("The time is:" + new Date()));
		t.start();

		JOptionPane.showMessageDialog(null, "退出?");
		System.exit(0);

	}

}
  • ArrayList的removeIf方法

試想如果當前我們需要清除list中所有null值,可以有如下寫法:

 List<String> list = new ArrayList<String>();
		 list.add("宋大寶");
		 list.add("大瀋陽");
		 list.add(null);
        System.out.println("初始時:"+ list.toString());
	        for(int i=0;i<list.size();i++) {
	        	if(list.get(i) == null) {
	        		list.remove(i);
	        	}
	        }
        System.out.println("過濾完:" + list.toString());

java1.8的ArrayList新增了一個removeIf方法,一行程式碼搞定:

list.removeIf(e -> e == null);

removeIf方法的引數是一個Predicate介面。這個介面專門用來傳遞lambda表示式:

public interface Predicate < T >
{
boolean test ( T t ) ;
// Additional default and static methods
}