一、接口的默認方法與靜態方法,也就是接口中可以有實現方法
1 public class Test { 2 public static void main(String[] args) { 3 Formula a=new For(); 4 a.calculate(1); 5 System.out.println(a.sqrt(8)); 6 7 8 } 9 interface Formula { 10 double calculate(int a); 11 default double sqrt(int a) {//這個方法可以在實現類重寫,或者直接使用 12 return Math.sqrt(a); 13 } 14 } 15 static class For implements Formula{ 16 @Override 17 public double calculate(int a) { 18 return 0; 19 } 20 21 @Override 22 public double sqrt(int a) { 23 return 0; 24 } 25 } 26 }
1 package com.ming.jdk18; 2 3 4 /** 5 * 6 * @author mingge 7 * jdk1.8接口支持靜態方法與默認方法 8 * 9 */ 10 public interface TestInterface { 11 12 //這個是默認方法 13 default String get(String aa,String bb){ 14 System.out.println("我是jdk1.8默認實現方法..."); 15 return ""; 16 } 17 18 String aa="2222"; 19 20 //這個是靜態方法 21 static void staticmethod(){System.out.println("我是靜態方法"+aa);} 22 }
1 package com.ming.jdk18; 2 3 4 public class Main { 5 6 7 public static void main(String[] args) { 8 TestInterface.staticmethod(); 9 } 10 11 12 }
以前的版本定義接口是不能有實現機制的,現在這樣用了一個default關鍵字后,就可以實現,然后子類可以重寫,也可以直接使用了。好處多多,感覺有點抽象類了...越來越靈活了。加入靜態方法后,你以后的工具類就可以參考接口來設計啦.這是一個優點啦.
二、Lambda 表達式
1 public class Test { 2 public static void main(String[] args) { 3 List<String> names = Arrays.asList("peter", "anna", "mike", "xenia"); 4 Collections.sort(names, new Comparator<String>() {//java以前老版本的寫法 5 @Override 6 public int compare(String a, String b) { 7 return b.compareTo(a); 8 } 9 }); 10 for(String name:names){ 11 System.out.println(name); 12 } 13 } 14 15 }
1 只需要給靜態方法 Collections.sort 傳入一個List對象以及一個比較器來按指定順序排列。通常做法都是創建一個匿名的比較器對象然后將其傳遞給sort方法。 2 在Java 8 中你就沒必要使用這種傳統的匿名對象的方式了,Java 8提供了更簡潔的語法,lambda表達式: 3 復制代碼 代碼如下: 4 5 Collections.sort(names, (String a, String b) -> { 6 return b.compareTo(a); 7 }); 8 9 看到了吧,代碼變得更段且更具有可讀性,但是實際上還可以寫得更短: 10 復制代碼 代碼如下: 11 12 Collections.sort(names, (String a, String b) -> b.compareTo(a)); 13 14 對於函數體只有一行代碼的,你可以去掉大括號{}以及return關鍵字,但是你還可以寫得更短點: 15 復制代碼 代碼如下: 16 17 Collections.sort(names, (a, b) -> b.compareTo(a)); 18 19 Java編譯器可以自動推導出參數類型,所以你可以不用再寫一次類型。接下來我們看看lambda表達式還能作出什么更方便的東西來:
lambda表達式的使用簡化了代碼。
三、函數式接口與靜態導入
Lambda表達式是如何在java的類型系統中表示的呢?每一個lambda表達式都對應一個類型,通常是接口類型。而“函數式接口”是指僅僅只包含一個抽象方法的接口,每一個該類型的lambda表達式都會被匹配到這個抽象方法。
因為默認方法不算抽象方法,所以你也可以給你的函數式接口添加默認方法。
我們可以將lambda表達式當作任意只包含一個抽象方法的接口類型,確保你的接口一定達到這個要求,你只需要給你的接口添加 @FunctionalInterface 注解,編譯器如果發現你標注了這個注解的接口有多於一個抽象方法的時候會報錯的。
1 public class Test { 2 public static void main(String[] args) { 3 Converter<String, Integer> a = (from) -> Integer.valueOf(from); 4 5 //Java 8 允許你使用 :: 關鍵字來傳遞方法或者構造函數引用 6 Converter<String, Integer> converter = Integer::valueOf;//這個是靜態方式導入 7 8 Integer m=a.convert("123"); 9 System.out.println(m); 10 test test=mmm -> "aaaa";//mmm代表你要傳入的參數 11 String testResult=test.aa("");//aa代表你要傳入的方法 12 System.out.println(testResult); 13 } 14 15 @FunctionalInterface 16 interface Converter<F, T> { 17 T convert(F from); 18 } 19 20 interface test{ 21 String aa(String mmm); 22 } 23 24 //使用函數式接口時,接口的定義只能有一個,@FunctionalInterface注解可有可無 25 }
四、Lambda 作用域
在lambda表達式中訪問外層作用域和老版本的匿名對象中的方式很相似。你可以直接訪問標記了final的外層局部變量,或者實例的字段以及靜態變量。
五、訪問局部變量
1 public class Test { 2 public static void main(String[] args) { 3 final int num = 1; 4 Converter<Integer, String> stringConverter = 5 (from) -> String.valueOf(from + num); 6 String str=stringConverter.convert(2); 7 System.out.println(str);//輸出3 8 //final關鍵字可以去掉,但是默認是存在的,所以,對num變量不能再次賦值修改 9 } 10 11 @FunctionalInterface 12 interface Converter<F, T> { 13 T convert(F from); 14 } 15 16 }
六、訪問對象字段與靜態變量
1 public class Test { 2 public static void main(String[] args) { 3 Lambda4 lambda4=new Lambda4(); 4 lambda4.testScopes(); 5 } 6 7 @FunctionalInterface 8 interface Converter<F, T> { 9 T convert(F from); 10 } 11 12 static class Lambda4 { 13 static int outerStaticNum=0; 14 int outerNum=0; 15 void testScopes() { 16 Converter<Integer, String> stringConverter1 = (from) -> { 17 outerNum = 23; 18 return String.valueOf(outerNum); 19 }; 20 String a=stringConverter1.convert(outerNum); 21 System.out.println(a);//輸出23 22 Converter<Integer, String> stringConverter2 = (from) -> { 23 outerStaticNum = 72; 24 return String.valueOf(outerStaticNum); 25 }; 26 27 } 28 } 29 30 //這里的意思是outerStaticNum與outerNum兩個參數可以多次賦值 31 32 }