java 8新特性學習之四:Java 8 lambda表示式初步第四回

孫小光發表於2016-06-15

一、作為引數傳遞lambda表示式
如前所述,lambda表示式可以用在任何提供了目標型別的上下文中。一種情況就是作為引數傳遞lambda表示式。
為了將lambda表示式作為引數傳遞,接受lambda表示式的引數的型別必須是與該lambda表示式相容的函式式介面的型別。

interface StringFunc{
  String func(String n);
}
class lambdasAsArgumentsDemo{
    static String stringOp(StringFunc sf,String s){
        return sf.func(s);
    }
    public static void main(String args[]){
        String inStr = "lambdas add power to Java";
        String outStr;
        System.out.println("Here is input string:"+inStr);
        outStr = stringOp((str)->str.toUpperCase(),inStr);
        System.out.println("The String in uppercase:"+outStr);
        outStr = stringOp((str)->{
                       String result = "";
                       int i;
                       for(i=0;i<str.length();i++)
                           if(str.charAt(i)!=' ')
                               result += str.charAt(i);
                       return result;
                       },inStr);
        System.out.println("The string with spaces removed:"+outStr);
        StringFunc reverse = (str)->{
            String result = "";
            int i;
            for(i=str.length()-1;i>=0;i--)
                result += str.charAt(i);
            return result;
        };
        System.out.println("The string reversed:"+stringOp(reverse,inStr));
    }
}

輸出結果為:
Here is input string: lambdas add power to Java
The string in uppercase: LAMBDAS ADD POWER TO JAVA
The string with spaces removed: lambdasaddpowertoJava
The string reversed: avaJ ot rewop dda sadbmal
最後要說明的一點是:除了變數初始化、賦值和引數傳遞以外,以下這些也構成了目標型別上下文:型別轉換、?運算子、陣列初始化器、return語句以及lambda表示式自身。
二、lambda表示式與異常
lambda表示式可以丟擲異常。但是,如果丟擲經檢查的異常,該異常就必須與函式式介面抽象方法的throws子句中列出的異常相容。

interface DoubleNumericArrayFunc{
    double func(double[] n) throws EmptyArrayException;
}
class EmptyArrayException extends Exception{
    EmptyArrayException(){
        super("Array Empty");
    }
}
class lambdaExceptionDemo{
    public static void main(String args[]) throws EmptyArrayException{
        double[] values = {1.0,2.0,3.0,4.0};
        DoubleNumericArrayFunc average = (n)->{
            double sum = 0;
            if(n.length==0)
               throw new EmptyArrayException();
            for(int i=0;i<n.length;i++)
              sum+=n[i];
            return sum/n.length;
        };
        System.out.println("The average is "+average.func(values));
        System.out.println("The average is"+average.func(new double[0]));
    }
}

以上程式要說明的是:
一、如果在lambda表示式是可以丟擲異常的,但與之對應的函式式介面中的方法定義必須有throws 異常類全名。否則無法通過編譯。
二、lambda表示式的引數型別是通過目標上下文推斷得出的,在本例中函式式介面中方法定義的引數是陣列型別。所以lambda表示式的引數n的型別也是陣列,明確寫出來,double[] n型別是可以的但是沒有必要。

相關文章