java8——lambda编程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010871004/article/details/85956494

lambda表达式

lambda表达式是一段可以传递的代码,因此它可以被执行一次或者多次。在java中jdk8之前是无法实现一个函数返回一个函数,或者是将一个方法作为参数传递给一个方法,lambda出现将改变这个局面。

lambda编程入门

Swing 是一个与平台无关的Java 类库,用来编写图形用户界面(GUI)。该类库有一个常见用法:为了响应用户操作,需要注册一个事件监听器。用户一输入,监听器就会执行一些操作。

button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent event) {
            System.out.println("button clicked");
        }
    });

我们通过lambda给上面的代码进行改写

button.addActionListener(event -> System.out.println("button clicked"));

和传入一个实现某接口的对象不同,我们传入了一段代码块——一个没有名字的函数。event 是参数名,和上面匿名内部类示例中的是同一个参数。-> 将参数和Lambda 表达式的主体分开,而主体是用户点击按钮时会运行的一些代码。
和使用匿名内部类的另一处不同在于声明event 参数的方式。使用匿名内部类时需要显式地声明参数类型ActionEvent event,而在Lambda 表达式中无需指定类型,程序依然可以编译。这是因为javac 根据程序的上下文(addActionListener 方法的签名)在后台推断出了参数event 的类型。这意味着如果参数类型不言而明,则无需显式指定。

lambda其他形式

有入参没有返回值的lambda表达式

Runnable runnable = () -> {
            System.out.println("hello world");
        };
new Thread(runnable).start();

有入参有返回值的lambda表达式

Function<String,String> func = str -> str.toUpperCase();
func.apply("hello world");

其实以上的lambda表达式都是函数式接口的实现,函数式接口的定义是只有一个抽象方法的接口是一个函数式接口,通常这样的函数上面都有@FunctionalInterface的annotation修饰,如何一个接口上没有这样的修饰符,但是该接口上有且仅有一个抽象方法,那么编译器在编译的时候依然将该函数当做是函数式接口。现在的接口定义中可以存在default方法和static方法。而如果该接口重写了Object根对象的某些非final方法,这样的函数也算是函数式接口。

@FunctionalInterface
public interface MyInterface {
    void method1();
    //void method2();
    String toString();
}

虽然当前的接口MyInterface 中存在两个抽象方法,但是toString()方法是存在于Object中的,所以这个方法不算是当前的接口中定义的方法。但是如果把method2()方法的注释去掉,这个方法就不再是一个函数式接口。

lambda表达式和final

lambda表达式其实也是事实上的匿名内部类,匿名内部类需要访问的变量为final的,但是在jdk8中,我们不再需要为变量强制的定义为final,但是我们在使用的时候也是不能够对变量进行改变,这个变量应该成为事实上的final。

public class Main {
    public static void main(String[] args) {
        int a = 4;
        Runnable runnable = () -> {a = 5; System.out.println(a);};
        new Thread(runnable).start();
    }
}

上面的代码会提示报错信息,在编辑的时候。Variable used in lambda expression should be final or effectively final。也就是在提示我们当前的变量不可以被重新赋值,应该是final的,只不过没有从形式给定义而已。

猜你喜欢

转载自blog.csdn.net/u010871004/article/details/85956494