Java-函数式编程(二)Lambda表达式

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> Java-函数式编程(二)Lambda表达式

“Lambda 表达式”(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。

认识lambda


    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名内部类的执行");
            }
        }).start();
    }

设计匿名内部类的目的,就是为了方便程序猿将代码作为数据来传递。但是你会发现,这个对象看起来是很多余的,所以我们不想传入对象,只想传入行为。


        new Thread(()-{
            System.out.println("lambda代替内部类");
        }).start();

和实现某接口的对象不同,我们传入了一段代码块–一个没有名字的函数。 -将参数和表达式主体分开,左边是参数,右边是方法体。

Lambda的不同形式


Runnable runnable =  ()- System.out.println("hello world");

该Lambda表达式不包含参数(因为是空括号)。


    interface Test{
        void oneParam(String name);
    }

        Test test = s - System.out.println("oneParam方法传递参数:"+s);
        test.oneParam("我是传递的值");

控制台输出:
oneParam方法传递参数:我是传递的值

(lambda只能用于函数式接口),如果参数只包含一个参数,可以省略参数的括号。


    interface Test2{
        int add(int a,int b);
    }
    Test2 test2 = (x,y) - x+y;
    int add = test2.add(10, 10);
    System.out.println(add);

控制台输出:
20

可以看到,我们在使用lambda的时候创建了一个函数 x+y Test2对象不是表示两个数字的和,而是表示两个数字相加的代码。以上的代码中,参数类型都是由编译器自己推断的,同样,我们可以明确的声明参数类型:


    interface Test3{
        long add(long a,long b);
    }

    Test3 test3 = (long x,long y) - x+y;
    long add = test3.add(10, 10);

引用值的要求

Error:(25, 64) java: 从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量


        String  name = "FantJ";
        Runnable runnable =  ()- System.out.println("hello " +name);
        runnable.run();

hello FantJ

上面这段代码,Lambda可以引用非final变量这个属性你可以早已了解,但是你更需要知道,java8只是放松了这一语法的限制,但实际上要求该变量还是final。

可以看到,不管 name在使用 lambda的前还是后做改动, lambda都会报错:表达式引用的本地变量必须是最终变量或实际上的最终变量,简单的,我们可以称他为既成事实上的final变量。所以,lambda也被称为闭包。

Lambda表达式类型

java中,所有方法都有返回类型,那lambda返回类型是什么呢。

是接口方法的返回类型。这一点前文有体现过。这里再详细解释下。


    interface Test{
        void oneParam(String name);
    }

拿这个例子来讲, oneParam方法表示一种行为:接受一个 String,返回 void。只要方法名和行为和Lambda表达式匹配即可完成调用。

注意:如果编译器猜不出参数和返回值的类型,则都将视为 Object处理。

关注后端技术精选,每天推送优质好文

Java-函数式编程(二)Lambda表达式
本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> Java-函数式编程(二)Lambda表达式


 上一篇
Java-函数式编程(一)初识篇 Java-函数式编程(一)初识篇
开发者使用Java8编写复杂的集合处理算法,只需要简单的代码就能在多喝cpu上高效运行,这就是Lambda表达式的初衷。 提示:函数式编程和语言无关,它是一种思想,任何语言都可以实现函数式编程,区别只是实现的难易程度不同而已。 在jav
下一篇 
Java-函数式编程(三)流(Stream) Java-函数式编程(三)流(Stream)
流使程序猿可以在抽象层上对集合进行操作。 从外部迭代到内部迭代 什么是外部迭代和内部迭代呢? 个人认为,外和内是相对集合代码而言。 如果迭代的业务执行在应用代码中,称之为外部迭代。 反之,迭代的业务执行在集合代码中,称为内部迭代(函数