java8中的Lambda表达式

    lambad表达式是一个匿名函数,既没有函数名的函数。在lambda表达式出现之前,java中更多使用的是匿名内部类所以有些刚刚接触lambda表达式的人会把lambda表达式误认为就是匿名内部类的简写。这里需要注意lambada表达式并不能简写所有的匿名内部类,准确的说lambda表达式表示的是一个函数式接口的实现,而函数式接口其实就是仅有一个需要实现的方法的接口。

    在介绍lambda表达式之前我想先说一下什么是面向接口编程。面向接口编程可以实现程序间的解耦,提高代码的灵活性和复用性。有时我们的方法的参数就是一个接口,这里我们并不是想要这个接口而是需要这个接口实现的代码,可是代码没有办法做为接口的参数传递,例如:File的String[] list(FilenameFilter filter)方法,里面需要传入一个FilenameFilter类型的参数,这里我们需要的其实就只是FilenameFilter这个接口的实现代码,所以有时接口常被用于传递代码,理解了这个思想lambda表达式就已经学会了一半了。

    java8提供了一种更为紧凑的传递代码的方法也就是lambda表达式。在介绍lambda表达式之前我们先来回顾一下java中使用匿名内部类来创建java多线程,代码如下:

public class TestLambda1 {
    
     public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("当前线程的名字是:"+Thread.currentThread().getName());
                
            }
        });
        t.start();
    }
}

这里我们通过了一个匿名内部类创建了一个线程。但是在java8之后,上面的代码可以简写成:

Thread lambdaThread = new Thread(
                ()->{System.out.println("当前线程的名字是:"+Thread.currentThread().getName());
                });
        lambdaThread.start();

可以看出,lambda表达式相比于内部类代码更加的简约易读,把接口和方法的名字都省略了,传递的代码更加的直观。lambda表达式是由方法的参数列表和方法体组成的,其中方法的参数类型可以省略,jvm会自动的判断参数的类型。当lambda表达式的函数体只有一句代码时,可以省略括号,这时主体的代码就是一个表达式,表达式的值就是函数的返回值。例如:

List<String> list = new ArrayList<String>();
list.sort((s1,s2)->s1.length()-s2.length());

    在lambda表达式中可以访问定义在lambda式之外的变量,但是在访问定义在方法中的局部变量时要求方法中的局部变量是不可变的,例如:

public class TestLambda1 {
    public static void main(String[] args) {
        String selfTest = "selfTest";
        selfTest="changeTest";
        Thread t = new Thread(()->{
            System.out.println(selfTest);
        });
        t.start();
        
    }
}

上面的代码会报错,因为selfTest是局部变量并且被重新赋值了。

原文地址:https://www.cnblogs.com/suyang-java/p/11655907.html