世界正在緩慢但肯定地發生變化。 經過更改后,Java有了JDK 7的全新外觀,Java社區期待JDK 8(可能還有JDK 9)所帶來的其余改進。
JDK 8的目標目的是填補JDK 7實施中的空白-該實施中剩下的部分難題,應該在2013年底之前為廣大讀者所用,目的是改善和增強JDK 7中的語言。三個特定方向:
- 生產率
- 性能
- 模塊化
因此,從明年開始,java將在所有地方(移動,云,桌面,服務器等)運行,但是會以一種改進的方式運行。 在接下來的內容中,我將簡短概述一下2013年的預期-緊接新年決議發布-之后,我將主要關注生產率方面,重點是項目lambda以及它的引入將如何影響我們的編碼方式。
生產率
在生產力方面,JDK 8的目標是兩個主要領域:–集合–通過引入語言的文字擴展與集合進行交互的一種更便捷的方式–注釋–增強了對注釋的支持,允許在當前非法的環境(例如基元)中編寫注釋
性能
向JDK 7添加Fork / Join框架是Java朝多核CPU邁出的第一步。 JDK 8通過為Java提供閉包支持(即lambda表達式),進一步走了這條路。 Java受影響最大的部分可能是Collections部分,其閉包與新添加的接口和功能將Java容器推向了新的高度。 除了要編寫的更具可讀性和更短的代碼之外,通過向集合提供將在內部執行的lambda表達式,平臺可以利用多核處理器。
模塊化
社區中最令人感興趣的作品之一是項目拼圖:“該項目的目標是為Java SE平臺設計和實現標準模塊系統,并將該系統應用于平臺本身和JDK。” 我使用過去式,是因為對于那些希望擺脫類路徑和類加載器的人來說,我們不得不推遲對Java 9的使用,因為那時候項目Jigsaw也被推遲了 。
要更清晰地了解如何重新發布Java Roadmap 2013:
- 2013/01/31 M6功能完成
- 2013/02/21 M7開發人員預覽
- 2013/07/05 M8最終版本候選
- 2013/09/09 GA全面上市
除了項目拼圖之外,即將出現的另一個重大變化(在此版本中)是對閉包的支持。 通過lambda表達式的幫助,它們將改善JDK的關鍵點。
Lambdas
入門
首先,首先應該獲得啟用了lambda的SDK。 在這個方向上,有兩種獲取方法:
*面向勇敢者的一種:從源頭構建
*方便的一種:下載已經編譯的SDK版本
最初,我從源頭開始構建它,但是由于時間緊缺以及與環境變量有關的警告過多,我選擇了惰性方法并采用了現有的JDK。 另一個重要的工具是用于編寫代碼的文本編輯器。 直到現在為止,它是最早出現的JDK版本,并在一段時間后啟用了IDE。 這次有所不同,這也許是由于openjdk提供的SDK的透明性和廣泛可用性。 幾天前,JetBrain實現了第一個啟用Java 8的IDE。 因此IntelliJ IDEA 版本 12是第一個提供對JDK 8支持的IDE,此外還有改進之處嗎? 因此,出于測試目的,我在Windows 7,x64計算機上將IntelliJ 12 Community Edition與JDK 8 b68一起使用。 對于那些喜歡Netbeans的人,可以下載具有lambda支持的每晚構建。
調整為適當的心態。
在開始使用新提供的功能來編寫經過改進和簡潔的代碼之前,必須先掌握幾個新概念,無論如何我還是需要的。
- 什么是lambda表達式? 查看lambda表達式的最簡單方法就像一種方法:“它提供了形式參數的列表,以及根據這些參數表示的主體(表達式或塊)。lambda表達式的參數可以聲明或推斷。 ,當形式參數具有推斷的類型時,則這些類型是從lambda表達式所針對的功能接口類型派生的。 從返回值的角度來看,lambda表達式可以是void兼容的-它們不返回任何值或值兼容-如果任何給定的執行路徑返回值。
lambda表達式的示例:(a) (int a, int b) -> a + b(b) (int a, int b) -> {if (a > b) {return a;} else if (a == b) {return a * b;} else {return b;}}
- 什么是功能接口? 功能接口是僅包含一個抽象方法的接口,因此表示單個方法協定。 在某些情況下,單個方法可能具有帶有覆蓋等效簽名的多個方法,在這種情況下,所有方法都代表一個方法。 除了通過創建和實例化類來創建接口實例的典型方式之外,還可以通過使用lambda表達式,方法或構造函數引用來創建功能接口實例。
功能接口示例:// custom built functional interface public interface FuncInterface {public void invoke(String s1, String s2); }
JAVA API的功能接口示例:
java.lang.Comparablejava.lang.Runnablejava.util.concurrent.Callablejava.awt.event.ActionListener
因此,讓我們看看線程的開始在將來可能會發生什么變化:
舊方法:new Thread(new Runnable() {@Overridepublic void run() {for (int i=0; i< 9; i++) {System.out.println(String.format('Message #%d from inside the thread!', i));}}}).start();
新方法:
new Thread(() -> {for (int i=0; i< 9; i++) {System.out.println(String.format('Message #%d from inside the thread!', i));}}).start();
即使我有一段時間沒有編寫任何與Java Swing,AWT相關的功能,我也不得不承認lambda將為Swing開發人員的Action偵聽器添加新鮮空氣:
JButton button = new JButton('Click');// NEW WAY:button.addActionListener( (e) -> {System.out.println('The button was clicked!');});// OLD WAY:button.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println('The button was clicked using old fashion code!');}});
- 誰/什么是SAM? SAM代表“單一抽象方法”,因此可以說一些捷徑可以說是SAM ==功能接口。 即使在最初的規范中,也將僅具有一種抽象方法的抽象類也視為SAM類型,一些人還是發現/猜測了原因。
- 方法/構造函數引用
- 什么是lambda表達式? 查看lambda表達式的最簡單方法就像一種方法:“它提供了形式參數的列表,以及根據這些參數表示的主體(表達式或塊)。lambda表達式的參數可以聲明或推斷。 ,當形式參數具有推斷的類型時,則這些類型是從lambda表達式所針對的功能接口類型派生的。 從返回值的角度來看,lambda表達式可以是void兼容的-它們不返回任何值或值兼容-如果任何給定的執行路徑返回值。
Lambda聽起來很好聽嗎? 但是以某種方式對功能接口的需求在某種程度上受到了限制–這是否意味著我只能使用包含單個抽象方法的接口? 并非完全如此-JDK 8提供了一種別名機制,該機制允許從類或對象中“提取”方法。 這可以通過使用新添加的::運算符來完成。 它可以應用于類–用于提取靜態方法,也可以應用于對象以提取方法。 相同的運算符也可以用于構造函數。
引用:
interface ConstructorReference{T constructor();
}interface MethodReference {void anotherMethod(String input);
}public class ConstructorClass {String value;public ConstructorClass() {value = 'default';}public static void method(String input) {System.out.println(input);}public void nextMethod(String input) {// operations}public static void main(String... args) {// constructor referenceConstructorReferencereference = ConstructorClass::new;ConstructorClass cc = reference.constructor();// static method referenceMethodReference mr = cc::method;// object method referenceMethodReference mr2 = cc::nextMethod;System.out.println(cc.value);}
}
- 接口中的默認方法
這意味著從版本8開始,java接口可以包含方法主體,因此簡單地說,java將支持多重繼承,而不會帶來通常的麻煩。 同樣,通過提供接口方法的默認實現,可以確保添加新方法不會在實現類中造成混亂。 JDK 8向java.util.Collection或java.util.Iterator之類的接口添加了默認方法,并通過此方法提供了一種在實際需要的地方更好地使用lambda的機制。
值得注意的接口添加:
java.util.stream.Streamablejava.util.stream.Stream
改善館藏的互動
在我看來,lambda項目所帶來的所有更改都是對語言的重大補充,這將使其與當前的標準保持一致,并使之更簡單,更精簡,但可能會對生產力產生最大的影響,并且最大的好處是+效果肯定是集合框架的改進。 不,沒有Collection 2框架,我們現在仍然需要處理類型擦除,但是Java將做出另一個重要的轉變:從外部迭代到內部迭代。 這樣,它為開發人員提供了一種以優雅的方式過濾和聚合集合的機制,此外還可以提高效率。 通過提供將在內部執行的lambda表達式,可以充分利用多核處理器的功能。 讓我們考慮以下情形:
一個。 考慮一個字符串列表,選擇所有大寫的字符串。 怎么寫?
舊方法:
//.....List inputList = new LinkedList<>();List upper = new LinkedList<>();// add elementsfor (String currentValue : inputList) {if (currentValue != null && currentValue.matches("[A-Z0-9]*")) {upper.add(currentValue);}}System.out.println(upper);
//….. 新方法:
//.....inputList.stream().filter(x -> (x != null && x.matches('[A-Z0-9]*'))).into(upper);
b。 考慮您想將所有提取的字符更改為小寫。 使用JDK8的方式如下所示:
// .....inputList.stream().filter(x -> (x != null && x.matches("[A-Z0-9]*"))).map(String::toLowerCase).into(upper);
C。 以及如何從所選集合中找出字符數
// ..... int sumX = inputList.stream().filter(x -> (x != null && x.matches("[A-Z0-9]*"))).map(String::length).reduce(0, Integer::sum);
使用的方法:
default Streamstream() // java.util.CollectionStreamfilter(Predicate predicate) // java.util.stream.StreamIntStream map(IntFunction mapper) //java.util.stream.Stream
d。 如果我想從集合中獲取每個元素并打印出來怎么辦?
//OLD WAY:
for (String current : list) {System.out.println(current);
}//NEW WAY:list.forEach(x -> System.out.println(x));
除了提到的功能之外,JDK 8還有其他有趣的消息,但是出于簡潔的原因,我將在這里停止。 有關它的更多信息,請參見JDK 8 Project lambda網站或JSR 337的網頁。
總而言之,Java正在向前發展,我個人喜歡它的發展方向,另一個興趣點是庫開發人員也開始采用JDK 8的時間點。 那肯定會很有趣。 謝謝您的時間和耐心,祝您圣誕快樂。
資源資源
Brian Goetz資源文件夾:
http://cr.openjdk.java.net/~briangoetz/lambda
方法/構造方法參考:
http://doanduyhai.wordpress.com/2012/07/14/java-8-lambda-in-details-part-iii-method-and-constructor-referencing
參考: Java –我們的JCG合作伙伴 Olimpiu Pop在Java Advent Calendar博客上對JDK 8的遠見。
翻譯自: https://www.javacodegeeks.com/2012/12/java-far-sight-look-at-jdk-8.html