簡而言之,java8的新特性就是:Lamdba函數(匿名函數),流,默認方法。java
Java8 的靈活使用,會使得代碼可讀性更好(前提是你的同事也使用,別人不會,你強行使用,會被噴的!!!)、簡潔易懂。編程
Collections.sort(inventory, new Comparator<Apple>() { public int compare(Apple a1, Apple a2){ return a1.getWeight().compareTo(a2.getWeight()); } });
注:此處使用的是匿名內部類,總體嘛,感受還能夠app
invertory.sort(comparing(Apple:getWeight))
注:此處使用的是Lambda表達式,它念起來就是「給庫存排序,比較蘋果的重量」編程語言
到此處,你可能不太明白Java8爲神馬能夠一行代碼搞定排序這個邏輯,不過,經過此處也見識了Java8的強大了,下面讓咱們總體認識一下。函數
編程語言中的函數一詞一般指的是方法。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 方法;請注意,咱們也開始用函數表明方法了。稍後咱們會解釋這個機制是如何工做的排序
在軟件工程中,一個衆所周知的問題就是,無論你作神嗎,用戶的需求都會變。
一種可能的解決方案是對你的選擇標準建模:你考慮的是蘋果,須要根據 Apple 的某些屬性(好比它是綠色的嗎?重量超過150克嗎?)來返回一個boolean 值。咱們把它稱爲謂詞(即一個返回 boolean 值的函數)。
讓咱們定義一個接口來對選擇標準建模:
public interface ApplePredicate{ boolean test (Apple apple); }
如今你就能夠用 ApplePredicate 的多個實現表明不一樣的選擇標準了,好比(如圖2-1所示):
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類,從而去掉沒必要要的代碼。
其代碼傳遞過程以下:
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以前是不可能作到的!