lambda表达式 Java 8 引入的函数式编程思想

java8,作为一个从java5以来最具革命性的版本。

lambda表达式和 stream 是自Java语言添加泛型(Generics)和注解(annotation)以来最大的变化。

java8中一个非常重要的特性就是lambda表达式,我们可以把它看成是一种闭包,它允许把函数当做参数来使用,是面向函数式编程的思想,一定程度上可以使代码看起来更加简洁。

虽然看着很先进,其实Lambda表达式的本质只是一个"语法糖",由编译器推断并帮你转换包装为常规的代码,因此你可以使用更少的代码来实现同样的功能。本人建议不要乱用,因为这就和某些很高级的黑客写的代码一样,简洁,难懂,难以调试,维护人员想骂娘。

如果之前见到的话都会觉得,lambda就是一个匿名函数,我们可以这样来理解就好了,Lambda表达式就是为了使得我们的代码更加的简洁。

例如以前我们使用匿名内部类来实现代码:

//匿名内部类写法
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("内部类写法");
            }
        }).start();
//使用lambda则更加简洁:
 new Thread(() -> System.out.println("lambda写法")).start();    

lambda表达式语法

基本语法:

(parameters) -> expression



(parameters) ->{ statements; }

(1)左边括号:lambda的形参列表,就好比是我们定义一个接口,里面有一个抽象方法,这个抽象方法的形参列表。

(2)箭头:lambda的操作符,所以你看见这个箭头心中知道这是一个lambda表达式就可以了。

(3)右边lambda体:就好比是我们实现了接口中的抽象方法。

函数式接口

想要对lambda表达式有一个深入的理解,我们需要去认识另外一个知识点,那就是函数式接口。

比如我们的Runnable就是一个函数式接口,我们可以到源码中看看。

他主要有如下的特点:

(1)含有@FunctionalInterface注解

(2)只有一个抽象方法

函数式接口能够接受匿名内部类的实例化对象,换句话说,我们可以使用匿名内部类来实例化函数式接口的对象,而Lambda表达式能够代替内部类实现代码的进一步简化。

方法引用

3.1 对象::实例方法,将lambda的参数当做方法的参数使用

 Consumer<String> sc = System.out::println;
        //等效
        Consumer<String> sc2 = (x) -> System.out.println(x);
        sc.accept("618, 狂欢happy");

类::静态方法,将lambda的参数当做方法的参数使用

//ClassName::staticMethod  类的静态方法:把表达式的参数值作为staticMethod方法的参数
        Function<Integer, String> sf = String::valueOf;
        //等效
        Function<Integer, String> sf2 = (x) -> String.valueOf(x);
        String apply1 = sf.apply(61888);

类::实例方法,将lambda的第一个参数当做方法的调用者,其他的参数作为方法的参数。开发中尽量少些此类写法,减少后续维护成本。

 //ClassName::instanceMethod  类的实例方法:把表达式的第一个参数当成instanceMethod的调用者,其他参数作为该方法的参数
        BiPredicate<String, String> sbp = String::equals;
        //等效
        BiPredicate<String, String> sbp2 = (x, y) -> x.equals(y);
        boolean test = sbp.test("a", "A");

构造函数

无参的构造方法就是类::实例方法模型,如:

 Supplier<User> us = User::new;
        //等效
        Supplier<User> us2 = () -> new User();
        //获取对象
        User user = us.get();

当有参数时

 //一个参数,参数类型不同则会编译出错
        Function<Integer, User> uf = id -> new User(id);
        //或加括号
        Function<Integer, User> uf2 = (id) -> new User(id);
        //等效
        Function<Integer, User> uf3 = (Integer id) -> new User(id);
        User apply = uf.apply(61888);

        //两个参数
        BiFunction<Integer, String, User> ubf = (id, name) -> new User(id, name);
        User 狂欢happy = ubf.apply(618, "狂欢happy");

总结

java8引入lambda表达式是接收了函数式编程语言的思想,例如scala之类的。

lambda表达式可以使代码看起来简洁,但一定程度上增加了代码的可读性以及调试的复杂性。

 

lambda表达式 Java 8 引入的函数式编程思想

上一篇:linux脚本启动jar


下一篇:Python3 -特定字符串的文件复制到另一个文件夹