標籤:局部變數 1.0 產生 uil try boolean red app 結果
一、基礎知識
lambda運算式本質上就是匿名方法,該方法不是獨立執行的,而是用於實現由函數式介面定義的方法,函數式介面僅包含一個抽象方法的介面。
無參數lambda運算式。
class Solution { interface MyNumber { double getValue(); } public static void main(String[] args) { MyNumber number = () -> 100; System.out.println(number.getValue()); }}View Code
帶參數lambda運算式。
class Solution { interface MyNumber { boolean isFactor(int a, int b); } public static void main(String[] args) { MyNumber number = (a, b) -> a % b == 0; System.out.println(number.isFactor(10, 5)); }}View Code
塊lambda運算式。
class Solution { interface MyNumber { double getAvr(double... arr); } public static void main(String[] args) { MyNumber number = (arr) -> { double res = 0; for (double i : arr) res += i; res /= arr.length; return res; }; double res = number.getAvr(1.0, 2.0, 3.0, 4.0, 5.0); System.out.println(res); }}View Code
二、泛型函數式介面
class Solution { interface MyNumber<T extends Number> { T getAvr(T... arr); } public static void main(String[] args) { MyNumber<Double> number = (arr) -> { double res = 0; for (double i : arr) res += i; res /= arr.length; return res; }; double res = number.getAvr(1.0, 2.0, 3.0, 4.0, 5.0); System.out.println(res); }}View Code
三、參數傳遞
可以lambda運算式作為參數傳遞給方法,為了將lambda運算式作為參數傳遞,接收lambda運算式的類型必須是與該lambda運算式相容的函數式介面的類型。
class Solution { interface MyString { String reverse(String s); } static String strOperate(MyString sf, String s) { return sf.reverse(s); } public static void main(String[] args) { String str = "Hello World"; MyString sf = (s) -> { StringBuilder builder = new StringBuilder(s); return builder.reverse().toString(); }; System.out.println(strOperate(sf, str)); }}View Code
四、異常
lambda運算式支援拋出異常,但是如果拋出經檢查的異常,就必須與函數式介面的抽象方法throws語句所列出的異常相容。
class Solution { static class EmptyArrayException extends Exception { EmptyArrayException() { super("Empty Array"); } } interface MyNumber { double getAvr(double... arr) throws EmptyArrayException; } public static void main(String[] args) { MyNumber number = (arr) -> { if (arr.length == 0) throw new EmptyArrayException(); double res = 0; for (double i : arr) res += i; res /= arr.length; return res; }; try { double res = number.getAvr(); System.out.println(res); } catch (EmptyArrayException exc) { System.out.println(exc.getMessage()); } }}View Code
五、變數捕獲
lambda運算式中可以訪問其外層範圍內定義的變數,但是這是會產生一種特殊情況,稱為變數捕獲。在這種情況下,lambda運算式只能使用實質上final的局部變數。final局部變數指的是第一次賦值之後值不能再發生變化的變數,這意味著lambda運算式不能修改外層範圍內的局部變數,即不能改變基本類型或者參考型別的數值,但是可以調用參考型別的方法。
六、方法引用
靜態方法引用。
class Solution { interface MyString { String reverse(String s); } static String strReverse(String s) { StringBuilder builder = new StringBuilder(s); return builder.reverse().toString(); } static String strOperate(MyString sf, String s) { return sf.reverse(s); } public static void main(String[] args) { String str = "Hello World"; System.out.println(strOperate(Solution::strReverse, str));//傳遞方法引用 }}View Code
執行個體方法引用。
class Solution { interface MyString { String reverse(String s); } String strReverse(String s) { StringBuilder builder = new StringBuilder(s); return builder.reverse().toString(); } static String strOperate(MyString sf, String s) { return sf.reverse(s); } public static void main(String[] args) { Solution solution = new Solution(); String str = "Hello World"; System.out.println(strOperate(solution::strReverse, str));//傳遞方法引用 }}View Code
泛型方法引用。
class Solution { interface MyArray<T> { boolean contain(T[] arr, T x); } static <T> boolean arrContain(T[] arr, T x) { for (T i : arr) if (i.equals(x)) return true; return false; } static <T> boolean arrOperate(MyArray<T> af, T[] arr, T x) { return af.contain(arr, x); } public static void main(String[] args) { Integer[] arr = {1, 2, 3, 4, 5}; System.out.println(arrOperate(Solution::<Integer>arrContain, arr, 0)); }}View Code
建構函式引用。
interface MyInterface { MyClass constructor(int val);}class MyClass { private int val; MyClass(int val) { this.val = val; } MyClass() { val = 0; } int getVal() { return val; }}class Solution { public static void main(String[] args) { MyInterface mf = MyClass::new;//匹配MyClass(int val) MyClass mc = mf.constructor(100); System.out.println(mc.getVal()); }}View Code
泛型建構函式引用。
interface MyInterface<T> { MyClass constructor(T val);}class MyClass<T> { private T val; MyClass(T val) { this.val = val; } T getVal() { return val; }}class Solution { public static void main(String[] args) { MyInterface<Double> mf = MyClass::new; MyClass mc = mf.constructor(100.0); System.out.println(mc.getVal()); }}View Code
七、預定義函數式介面
通常我們不需要自己定義函數式介面,Java已經提供了一些預定義的函數式介面。
| UnaryOperator<T> |
對類型為T的對象應用一元運算並返回結果,方法名為apply。 |
| BinaryOperator<T> |
對類型為T的兩個對象進行操作並返回結果,方法名為apply。 |
| Consumer<T> |
對類型為T的對象應用操作,方法名為accept。 |
| Supplier<T> |
傳回型別為T的對象,方法名為get。 |
| Function<T, R> |
對類型為T的對象應用操作,並傳回型別為R的對象,方法名為apply。 |
| Predicate<T> |
確定類型為T的對象是否滿足某種約束,返回布爾值,方法名為test。 |
預定義函數式介面使用
import java.util.function.BinaryOperator;class Solution { public static void main(String[] args) { BinaryOperator<Integer> op = (a, b) -> a + b; System.out.println(op.apply(10, 100));//110 }}View Code
Java筆記:匿名方法