java8新特性:一,Lambda 表达式

java8新特性:一,Lambda 表达式

1
Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。

Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)

使用 Lambda 表达式可以使代码变的更加简洁紧凑。

语法
lambda 表达式的语法格式如下:

(parameters) -> expression

(parameters) ->{ statements; }

以下是lambda表达式的重要特征:

可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。

Lambda 表达式实例
Lambda 表达式的简单例子:(和javascript的箭头函数语法相仿,都是无参数一个(),1个参数可省略(),多个参数需要())

// 1. 不需要参数,返回值为 5
() -> 5

// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x

// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y

// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y

// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)

public class Lam {
    public static void main(String[] args) {
        //类型声明(Integer::sum,静态方法引用)
//        public static int sum(int a, int b) {
//            return a + b;
//        }
//        XiaoXuMath addition= Integer::sum;
        XiaoXuMath addition= (int a,int b)->a+b;
        //不用类型声明
        XiaoXuMath subtraction=(a,b)->a-b;
        //大括号中的返回语句
        XiaoXuMath mul=(int a,int b)->{return a*b;};
        //没有大括号及返回语句
        XiaoXuMath div=(int a,int b)->a/b;
        System.out.println(addition.oper(12,54));
        Lam h=new Lam();
        System.out.println("12+54:"+h.getValue(12,54,addition));
        System.out.println("7-9:"+h.getValue(7,9,subtraction));
        System.out.println("5*4:"+h.getValue(5,4,mul));
        System.out.println("28/7:"+h.getValue(28,7,div));
    }
    interface XiaoXuMath{
        int oper(int a,int b);
    }
    private int getValue(int x,int y,XiaoXuMath m){
        return m.oper(x,y);
    }
}
66
12+54:66
7-9:-2
5*4:20
28/7:4

使用 Lambda 表达式需要注意以下两点:

Lambda 表达式主要用来定义行内执行的方法类型接口,例如,一个简单方法接口。在上面例子中,我们使用各种类型的Lambda表达式来定义XiaoXuMath接口的方法。

Lambda 表达式免去了使用匿名方法的麻烦,并且给予Java简单但是强大的函数化的编程能力。

变量作用域

lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。
java8新特性:一,Lambda 表达式

public class UseLam {
    final static String salutation="Hello?";
    static String test="我是test";
    public static void main(String[] args) {
        Greet g=msg -> System.out.println(salutation+msg);
        g.sayMessage("xiaoxu!");
        WantToTest w1=e->e+"nihao";
        System.out.println(w1.test1(test));
        System.out.println(test);
    }
    interface Greet{
        void sayMessage(String msg);
    }
    interface WantToTest{
        String test1(String x1);
//        void test2(String x2);
    }
}
Hello?xiaoxu!
我是testnihao
我是test

也可以直接在 lambda 表达式中访问外层的局部变量:

public class UseLam{
    public static void main(String[] args) {
        int num=1;
        Converter<Integer,String> c=i -> System.out.println("你好:"+String.valueOf(i+num));
        c.convert(45);
        System.out.println(c);
        System.out.println(c.getClass());
    }
    @FunctionalInterface
    public interface Converter<T1,T2>{
        void convert(int i);
    }
}
你好:46
com.xiaoxu.boot.learn.UseLam$$Lambda$1/1198108795@6f539caf
class com.xiaoxu.boot.learn.UseLam$$Lambda$1/1198108795

lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)
java8新特性:一,Lambda 表达式
在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。

public static void main(String[] args) {
    String x="";
    Comparator<String> c=(f,s)->Integer.compare(f.length(),s.length());
    String a="1";
    String b="78";
    System.out.println(c.compare(a, b));
}
-1

Comparator是函数式接口,所以可以实例化赋值lambda、方法引用、构造方法引用
java8新特性:一,Lambda 表达式

但是修改成功局部变量同名的参数后,会报错:
java8新特性:一,Lambda 表达式
java8新特性:一,Lambda 表达式

上一篇:Creating network "soft_default" with the default driver ERROR: cannot create network e5b60


下一篇:Python for Data Science - Creating standard data graphics