Java基础之Lambda表达式

Lambda表达式可以由编译器推断并转换包装为常规的代码,因此可以使用更少的代码来实现同样的功能。Java中使用Lambda表达式的前提是:必须有“函数式接口

1.函数式接口

有且仅有一个抽象方法的接口,叫做函数式接口。
注意:

  • 是接口
  • 有且仅有一个抽象方法:不能没有,不能有2个及以上,同时可以有默认方法、静态方法等。

    如何万无一失地检测当前接口是不是函数式接口呢? 用一个固定的格式写在public interface之前一行即可:

 @FunctionalInterface
 public interface 函数式接口名{
 //.....
 }

如下面代码定义的接口就是函数式接口:只有一个抽象方法。

@FunctionalInterface 
public interface Calculator {
    //抽象方法
    public abstract int sum(int x,int z);

    //默认方法
    public default int getMax(int x,int z) {
        return x>z?x:z;
    }
}

2.Lambda表达式标准接口

Lambda表达式要想使用,一定要有函数式接口的推断环境
1.要么通过方法的参数类型来确定是哪个函数式接口;
2.要么通过赋值操作来确定是哪个函数式接口;(等号左侧的对象类型)
Lambda的格式就是为了将抽象方法的头,翻译为以下3点:
1.一些参数:方法参数
2.一个箭头:->
3.一些代码:方法体
例如抽象方法:public abstract int sum(int x,int z);
翻译成为Lambda的标准格式:

 (int x, int z)->{return x+z;}

省略格式:在Lambda表达式中,凡是可以推导的,都可以省略
1.Lambda表达式中的参数类型可以省略不写;
2.如果参数有且只有一个,那么小括号可以省略不写;
3.如果语句只有一个,那么大括号和return语句也可以省略;

例:定义一个函数式接口Calculator

@FunctionalInterface 
public interface Calculator {
    public abstract int sum(int x,int z);
    }
}
public class LambdaDemo {
    public static void main(String[] args) {

        //标准格式
        method((int x,int y)->{return x+y;});

        //省略格式
        method((a,b)->a+b);

        //根据赋值语句左侧的类型推断
        Calculator pa = (int x,int y)->{return x+y;};
        method(pa);

        //错误写法:
        //(int x,int y)->{return x+y;};//没有上下文推断,没有传参数,没有赋值

    }
    public static void method(Calculator calculator) {
        int s = calculator.sum(100,200);
        System.out.println(s);
    }
}

运行结果:
这里写图片描述

3.Lambda表达式的冗余

来看一个例子:
首先定义一个类PrintClass,这个类有一个静态方法print,用于打印给定的字符串:

public class PrintClass {

    public static void printStr(String str) {
        System.out.println(str);
    }
}

然后我定义了一个函数式接口PrintMsg :

@FunctionalInterface
public interface PrintMsg {
    public abstract void print(String msg);
}

在main函数里我用Lambda表达式指定了接口的作用:

public class LambdaDemo {
    public static void main(String[] args) {
        methodPrint((String str)-> {System.out.println(str);});

    }
    public static void methodPrint(PrintMsg printMsg) {
        printMsg.print("Jungle");
    }
}

运行结果如图:
这里写图片描述
是我们想要的结果。但是我们发现,在我们定义的类PrintClass里的静态方法printStr已经实现了这个功能,但是在main里又通过Lambda表达式重新写了一遍,这没有必要,能不能通过Lambda表达式直接调用已有的方法呢?

4.Lambda引用类的静态方法和成员方法

上面的问题的答案是肯定的。这即是通过引用类的方法来实现。分为两种,静态方法和成员方法。
对于静态方法,通过类名::静态方法名;
对于成员方方法,通过类的对象名::成员方法名;
还是上面的例子:

public class LambdaDemo {
    public static void main(String[] args) {
        methodPrint(PrintClass::printStr);//引用类的静态方法
    }
    public static void methodPrint(PrintMsg printMsg) {
        printMsg.print("Jungle");
    }
}

猜你喜欢

转载自blog.csdn.net/sinat_21107433/article/details/81140185