Lambda的用法

Lambda表达式的本质只是一个语法糖,由编译器推断并帮你转换包装为常规的代码,因此你可以使用更少的代码来实现同样的功能。

1.

lambda 表达式的语法格式如下:
  (parameters) -> expression
  或
  (parameters) ->{ statements; }

lambda表达式的重要特征:

  • 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
  • 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
  • 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
  • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。
// 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 Main {
  public static void main(String[] argv) {
    Processor stringProcessor = str -> str.length();
    String name = "Java Lambda";
    int length = stringProcessor.getStringLength(name);
    System.out.println(length);
  }
}


interface Processor {
  int getStringLength(String str);
}
输出:11

2.

lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误
lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)

String text = "test";
List list = Arrays.asList(1,2);
list.forEach(value -> {
    System.out.println(text + value);
});
输出:
test1
test2
        String text = "test";
        text="test change";
        List list = Arrays.asList(1,2);
        list.forEach(value -> {
            System.out.println(text + value);
        });
//报错: 从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量

在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量

String first = "";  
Comparator comparator = (first, second) -> Integer.compare(first.length(), second.length()); 
//编译出错:已在方法 main(java.lang.String[])中定义了变量 first

3.

方法引用:若Lambda体中的内容有方法已经实现了,那么我们可以使用"方法引用"
主要有三种语法格式:

  • 对象::实例方法名
  • 类::静态方法名
  • 类::实例方法名

注意:

    1. Lambda体中调用方法的参数列表与返回值类型,要与函数式接口中抽象方法的函数列表和返回值类型保存一致
    1. 若Lambda参数列表中的第一个参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用ClassName::method
//1.对象::实例方法名
     Employee emp = new Employee(101, "lily", 18);
        Supplier sup = () -> emp.getName();
        System.out.println(sup.get());

        System.out.println("----------------------------------");
     
        Supplier sup2 = emp::getName;
        System.out.println(sup2.get());

//2.类::静态方法名
Arrays.asList("We will build a great wall and Mexico will pay."
        .split(" "))
        .forEach(MyLogger::log); //log(..)就是MyLogger类中的静态方法  

//3.类::实例方法名
    BiPredicate bp = (x, y) -> x.equals(y);
        System.out.println(bp.test("abcde", "abcde"));

        System.out.println("-----------------------------------------");
         //前提:第一个参数是实例方法的调用者,第二个参数是实例方法的参数
        //例如 x 是equals方法的调用者,y是实例方法的参数
        BiPredicate bp2 = String::equals;
        System.out.println(bp2.test("abc", "abc"));

构造器引用 :
ClassName::new
构造器的参数列表,需要与函数式接口中参数列表保持一致

        Supplier sup = ()-> new Employee();
        Employee emp = sup.get();
        //构造器引用
        //根据参数列表自动匹配构造器
        Supplier sup2 = Employee::new;
        emp = sup2.get();
        System.out.println(emp);

你可能感兴趣的:(Lambda的用法)