栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java中Lambda表达式使用及详解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java中Lambda表达式使用及详解

Java中Lambda表达式使用及详解

前言
一、Lambda表达式的简介

Lambda表达式(闭包):java8的新特性,lambda运行将函数作为一个方法的参数,也就是函数作为参数传递到方法中。使用lambda表达式可以让代码更加简洁。

Lambda表达式的使用场景:用以简化接口实现。

关于接⼝实现,可以有很多种⽅式来实现。例如:设计接⼝的实现类、使⽤匿名内部类。 但是lambda表达式,⽐这两种⽅式都简单。

package com.qf.test;


public class Test04 {
    public static void main(String[] args) {
        //使用lambda表达式实现接口
        Test test = () -> {
            System.out.println("test");
        };
        test.test();
    }
}

interface Test{
    public void test();
}
二、Lambda表达式对接口的要求

虽然说,lambda表达式可以在⼀定程度上简化接⼝的实现。但是,并不是所有的接⼝都可以使⽤lambda表达式来简洁实现的。

lambda表达式毕竟只是⼀个匿名⽅法。当实现的接⼝中的⽅法过多或者多少的时候,lambda表达式都是不适⽤的。

lambda表达式,只能实现函数式接⼝。

1.函数式接口

如果说,⼀个接⼝中,要求实现类必须实现的抽象⽅法,有且只有⼀个!这样的接⼝,就是函数式接⼝。

代码如下(示例):

//有且只有一个实现类必须要实现的抽象方法,所以是函数式接口
interface Test{
    public void test();
}
2.@FunctionalInterface

是⼀个注解,⽤在接⼝之前,判断这个接⼝是否是⼀个函数式接⼝。 如果是函数式接⼝,没有任何问题。如果不是函数式接⼝,则会报错。功能类似于 @Override。
代码如下(示例):

@FunctionalInterface
interface Test{
    public void test();
}
3.Lambda表达式的语法 1.Lambda表达式的基础语法

lambda表达式,其实本质来讲,就是⼀个匿名函数。因此在写lambda表达式的时候,不需要关⼼⽅法名是什么。

实际上,我们在写lambda表达式的时候,也不需要关⼼返回值类型。

我们在写lambda表达式的时候,只需要关注两部分内容即可:参数列表和⽅法体

lambda表达式的基础语法:
(参数1,参数2,…) -> {
方法体
};

参数部分:⽅法的参数列表,要求和实现的接⼝中的⽅法参数部分⼀致,包括参数的数量和类型。

⽅法体部分 : ⽅法的实现部分,如果接⼝中定义的⽅法有返回值,则在实现的时候,注意返回值的返回。

-> : 分隔参数部分和⽅法体部分。

代码示例:

package com.qf.test;


public class Test04 {
    public static void main(String[] args) {
        //使用lambda表达式实现接口

        //无参
//        Test test = () -> {
//            System.out.println("test");
//        };

        //有参
//        Test test = (name,age) -> {
//            System.out.println(name+age+"岁了!");
//        };
//        test.test("小新",18);

        //有参+返回值
        Test test = (name,age)  -> {
            System.out.println(name+age+"岁了!");
            return age + 1;
        };
        int age = test.test("小新",18);
        System.out.println(age);

    }
}

//无参
//interface Test{
//    public void test();
//}

//有参 无返回值
//interface Test{
//    public void test(String name,int age);
//}

//有参 有返回值
interface Test{
    public int test(String name,int age);
}
4.Lambda表达式的语法进阶

参数部分的精简

参数的类型

由于在接⼝的⽅法中,已经定义了每⼀个参数的类型是什么。⽽且在使⽤lambda表达式实现接⼝的时候,必须要保证参数的数量和类 型需要和接⼝中的⽅法保持⼀致。因此,此时lambda表达式中的参数的类型可以省略不写。

注意点:

如果需要省略参数的类型,要保证:要省略, 每⼀个参数的类型都必须省略不写。绝对不能出现,有的参数类型省略了,有的参数类型没有省略。

        //有参+返回值
        Test test = (name,age)  -> {
            System.out.println(name+age+"岁了!");
            return age + 1;
        };
        int age = test.test("小新",18);
        System.out.println(age);

参数的⼩括号

如果⽅法的参数列表中的参数数量 有且只有⼀个,此时,参数列表的⼩括号是可以省略不写的。

注意事项:

只有当参数的数量是⼀个的时候, 多了、少了都不能省略。省略掉⼩括号的同时, 必须要省略参数的类型

        //一个参数
        Test test = name -> {
            System.out.println(name+"test");
        };
        test.test("小新");

⽅法体部分的精简

⽅法体⼤括号的精简

当⼀个⽅法体中的逻辑,有且只有⼀句的情况下,⼤括号可以省略

Test test = name -> System.out.println(name+"test");
        test.test("小新");

return的精简

如果⼀个⽅法中唯⼀的⼀条语句是⼀个返回语句, 此时在省略掉⼤括号的同时, 也必须省略掉return。

Test test = (a,b) -> a+b;
三、函数引用

lambda表达式是为了简化接⼝的实现的。在lambda表达式中,不应该出现⽐较复杂的逻辑。如果在lambda表达式中出现了过于复杂的逻辑,会对程序的可读性造成⾮常⼤的影响。如果在lambda表达式中需要处理的逻辑⽐较复杂,⼀般情况会单独的写⼀个⽅法。在lambda表达式中直接引用这个⽅法即可。

函数引⽤:引⽤⼀个已经存在的⽅法,使其替代lambda表达式完成接⼝的实现

1.静态⽅法的引⽤

语法:类::静态方法

注意事项:

在引⽤的⽅法后⾯,不要添加⼩括号。引⽤的这个⽅法,参数(数量、类型)和返回值,必须要跟接⼝ 中定义的⼀致

package com.qf.test;


public class Test05 {
    public static void main(String[] args) {
        //实现多个参数,一个返回值的接口
        //对一个静态方法的引用,语法:类::静态方法
        Test1 test1 = Calculator::calculate;
        System.out.println(test1.test(4,5));
    }
}

class Calculator{
    public static int calculate(int a,int b ){
        // 稍微复杂的逻辑:计算a和b的差值的绝对值
        if (a > b) {
            return a - b;
        }
        return b - a;
    }
}

interface Test1{
    int test(int a,int b);
}
2.非静态⽅法的引用

语法:对象::⾮静态⽅法

注意事项:

在引⽤的⽅法后⾯,不要添加⼩括号。引⽤的这个⽅法, 参数(数量、类型) 和 返回值, 必须要跟接⼝中定义的⼀致。

package com.qf.test;


public class Test06 {
    public static void main(String[] args) {
        //对非静态方法的引用,需要使用对象来完成
        Test2 test2 = new Calculator()::calculate;
        System.out.println(test2.calculate(2, 3));
    }
    private static class Calculator{
        public int calculate(int a, int b) {
            return a > b ? a - b : b - a;
         }
    }
}
interface Test2{
    int calculate(int a,int b);
}
3.构造方法的引用

使⽤场景

如果某⼀个函数式接⼝中定义的⽅法,仅仅是为了得到⼀个类的对象。此时我们就可以使⽤构造⽅法的引⽤,简化这个⽅法的实现。

语法:类名::new

注意事项:可以通过接⼝中的⽅法的参数, 区分引⽤不同的构造⽅法。

四、Lambda表达式需要注意的问题

这⾥类似于局部内部类、匿名内部类,依然存在闭包的问题。

如果在lambda表达式中,使⽤到了局部变量,那么这个局部变量会被隐式的声明为 final。是⼀个常量,不能修改值。


总结

以上就是Lambda表达式相关内容,本文仅简单介绍了Lambda表达式的使用,祝各位小伙伴们学习愉快,欢迎交流!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/781047.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号