1. Lambda表达式

Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。可以使代码变的更加简洁紧凑。

1.1 基本语法:

(参数列表) -> {代码块}

需要注意:

  • 参数类型可省略,编译器可以自己推断
  • 如果只有一个参数,圆括号可以省略
  • 代码块如果只是一行代码,大括号也可以省略
  • 如果代码块是一行,且是有结果的表达式,return可以省略

注意:事实上,把Lambda表达式可以看做是匿名内部类的一种简写方式。当然,前提是这个匿名内部类对应的必须是接口,而且接口中必须只有一个函数!Lambda表达式就是直接编写函数的:参数列表、代码体、返回值等信息,用函数来代替完整的匿名内部类

1.2 用法示例

示例1:多个参数

准备一个集合:

// 准备一个集合
List<Integer> list = Arrays.asList(10, 5, 25, -15, 20);

假设我们要对集合排序,我们先看JDK7的写法,需要通过匿名内部类来构造一个Comparator

// Jdk1.7写法
Collections.sort(list,new Comparator<Integer>() {
    @Override
    public int compare(Integer o1, Integer o2) {
        return o1 - o2;
    }
});
System.out.println(list);// [-15, 5, 10, 20, 25]

如果是jdk8,我们可以使用新增的集合API:sort(Comparator c)方法,接收一个比较器,我们用Lambda来代替Comparator 的匿名内部类:

// Jdk1.8写法,参数列表的数据类型可省略:
list.sort((i1,i2) -> { return i1 - i2;});

System.out.println(list);// [-15, 5, 10, 20, 25]

对比一下Comparator中的compare()方法,你会发现:这里编写的Lambda表达式,恰恰就是compare()方法的简写形式,JDK8会把它编译为匿名内部类。是不是简单多了!

别着急,我们发现这里的代码块只有一行代码,符合前面的省略规则,我们可以简写为:

// Jdk8写法
// 因为代码块是一个有返回值的表达式,可以省略大括号以及return
list.sort((i1,i2) -> i1 - i2);
示例2:单个参数

还以刚才的集合为例,现在我们想要遍历集合中的元素,并且打印。

先用jdk1.7的方式:

// JDK1.7遍历并打印集合
for (Integer i : list) {
    System.out.println(i);
}

jdk1.8给集合添加了一个方法:foreach() ,接收一个对元素进行操作的函数:

// JDK1.8遍历并打印集合,因为只有一个参数,所以我们可以省略小括号:
list.forEach(i -> System.out.println(i));
实例3:把Lambda赋值给变量

Lambda表达式的实质其实还是匿名内部类,所以我们其实可以把Lambda表达式赋值给某个变量。

// 将一个Lambda表达式赋值给某个接口:
Runnable task = () -> {
    // 这里其实是Runnable接口的匿名内部类,我们在编写run方法。
    System.out.println("hello lambda!");
};
new Thread(task).start();

不过上面的用法很少见,一般都是直接把Lambda作为参数。

示例4:隐式final

Lambda表达式的实质其实还是匿名内部类,而匿名内部类在访问外部局部变量时,要求变量必须声明为final!不过我们在使用Lambda表达式时无需声明final,这并不是说违反了匿名内部类的规则,因为Lambda底层会隐式的把变量设置为final,在后续的操作中,一定不能修改该变量:

正确示范:

// 定义一个局部变量
int num = -1;
Runnable r = () -> {
    // 在Lambda表达式中使用局部变量num,num会被隐式声明为final
    System.out.println(num);
};
new Thread(r).start();// -1

错误案例:

// 定义一个局部变量
int num = -1;
Runnable r = () -> {
    // 在Lambda表达式中使用局部变量num,num会被隐式声明为final,不能进行任何修改操作
    System.out.println(num++);
};
new Thread(r).start();//报错

results matching ""

    No results matching ""