java8 (一):爲神馬要學習java8?

1. java8新特性

1.1 新特性介紹

簡而言之,java8的新特性就是:Lamdba函數(匿名函數),流,默認方法。java

Java8 的靈活使用,會使得代碼可讀性更好(前提是你的同事也使用,別人不會,你強行使用,會被噴的!!!)、簡潔易懂編程

1.2 示例展現(對庫存中的蘋果按照蘋果排序)


  • 之前的寫法
Collections.sort(inventory, new Comparator<Apple>() {
        public int compare(Apple a1, Apple a2){
            return a1.getWeight().compareTo(a2.getWeight());
        }
});

:此處使用的是匿名內部類,總體嘛,感受還能夠app

  • java8的寫法
invertory.sort(comparing(Apple:getWeight))

:此處使用的是Lambda表達式,它念起來就是「給庫存排序,比較蘋果的重量」編程語言

到此處,你可能不太明白Java8爲神馬能夠一行代碼搞定排序這個邏輯,不過,經過此處也見識了Java8的強大了,下面讓咱們總體認識一下。函數

2. Lambda函數

編程語言中的函數一詞一般指的是方法。java8中新增了函數----值得一種新形式。做爲值的函數有何益處,Java8的設計者容許方法做爲值,讓編程更輕鬆。設計

java8的第一個新功能就是方法引用。比方說你想要篩選一個目錄中全部隱藏的文件。你須要編寫一個方法,而後給它一個File,它就會告訴你文件是否是隱藏的。幸虧,File 類面有一個叫作isHidden的方法。咱們能夠把它看作一個函數,接受一個File,返回一個boolean值.但要用它作篩選,你須要把它包在一個 FileFilter 對象裏,而後傳遞給 File.listFiles 方法,以下所示:code

File[] hiddenFiles = new File(".").listFiles(new FileFilter() {
	public boolean accept(File file) {
		return file.isHidden();
	}
});

呃!真可怕!雖然只有三行,但這三行可真夠繞的。咱們第一次碰到的時候確定都說過:「非 得這樣不可嗎?」咱們已經有一個方法 isHidden 可使用,爲何非得把它包在一個囉嗦的 FileFilter 類裏面再實例化呢?由於在Java 8以前你必須這麼作!對象

java8的作法以下,blog

File[]                                                                            hiddenFiles = new File(".").listFiles(File::isHidden);

哇!酷不酷?你已經有了函數 isHidden ,所以只需用Java 8的方法引用 :: 語法(即「把這 個方法做爲值」)將其傳給 listFiles 方法;請注意,咱們也開始用函數表明方法了。稍後咱們會解釋這個機制是如何工做的排序

3. 行爲參數化傳遞代碼

在軟件工程中,一個衆所周知的問題就是,無論你作神嗎,用戶的需求都會變。

一種可能的解決方案是對你的選擇標準建模:你考慮的是蘋果,須要根據 Apple 的某些屬性(好比它是綠色的嗎?重量超過150克嗎?)來返回一個boolean 值。咱們把它稱爲謂詞(即一個返回 boolean 值的函數)。

3.1. 建模

讓咱們定義一個接口來對選擇標準建模:

public interface ApplePredicate{
	boolean test (Apple apple);
}

3.2 寫抽象實例類

如今你就能夠用 ApplePredicate 的多個實現表明不一樣的選擇標準了,好比(如圖2-1所示):

3.3根據抽象條件篩選

public static List<Apple> filterApples(List<Apple> inventory,
ApplePredicate p){
	List<Apple> result = new ArrayList<>();
	for(Apple apple: inventory){
		if(p.test(apple)){
			result.add(apple);
		}
	}
	return result;
}

作到此處,你已經很NB了,filterApples的行爲取決於你經過ApplePredicate對象傳遞的代碼,換句話說,你把filterApples方法的行爲參數化了。

但使人遺憾的是,因爲該 filterApples 方法只能接受對象,因此你必須把代碼包裹在 ApplePredicate 對象裏。你的作法就相似於在內聯「傳遞代碼」,由於你是經過一個實現了 test 方法的對象來傳遞布爾表達式的。

經過使用Lambda,你能夠直接把表達式 "red".equals(apple.getColor()) &&apple.getWeight() > 150 傳遞給 filterApples 方法,而無需定義多個 ApplePredicate類,從而去掉沒必要要的代碼。

其代碼傳遞過程以下:

3.4 經過匿名內部類的方式比較簡單,請自行嘗試

3.5 經過Lambda表達式

public interface Predicate<T>{
		boolean test(T t);
	}
	
	public static <T> List<T> filter(List<T> list, Predicate<T> p){
			List<T> result = new ArrayList<>();
		for(T e: list){
			if(p.test(e)){
				result.add(e);
			}
		}
		return result;
	}

如今你能夠把 filter 方法用在香蕉、桔子、 Integer 或是 String 的列表上了。這裏有一個

使用Lambda表達式的例子:

List<Apple> redApples =
	filter(inventory, (Apple apple) -> "red".equals(apple.getColor()));
List<Integer> evenNumbers =
	filter(numbers, (Integer i) -> i % 2 == 0);

酷不酷?你如今在靈活性和簡潔性之間找到了最佳平衡點,這在Java 8以前是不可能作到的!

相關文章
相關標籤/搜索