您当前的位置:首页 > 计算机 > 编程开发 > Java

Java8之新特性--Lambda表达式详解

时间:02-13来源:作者:点击数:

一、Lambda表达式背景:

Lambda称之为函数式编程,其实早在C++、C#、PHP、JavaScript、React、Python等语言中Lambda已经问世了,并广泛的被使用。在Java8的更新之后,也把Lambda表达式引入了进来,它的出现打破了Java语法的常规,让代码看上去更加简洁。

二、Lambda表达式简介、作用以及缺陷(针对Java而言)

1、简介:

Lambda表达式允许将一段方法体(函数)作为参数传递给其他方法,在遇到多态的情况下,我们不需要专门针对父类的方法进行重写(@Override),将父类方法的参数设定为函数式接口,这样子类在调用父类方法时,只需要将实现的方法体作为参数传递到父类。

2、作用:

Lambda的使用既可以减少代码量,还可以使代码看上去更加简洁(可以使多行代码变为一行)

3、缺陷

Lambda的使用会降低代码的可读性,虽然代码看上去简洁了很多,但是公司新人或者审查代码的leader读起来比较费劲

注:该章节主要为大家介绍了Lamdba表达式的写法,结合集合的遍历让大家认识下Lamdba的写法!

三、Lamdba表达式讲解---针对Java的集合遍历讲解

1、在Java8之前我们遍历集合常用的方式是for、Java5推出的foreach或者iterator迭代器

Java8之前遍历代码展示:

public class Java8OfLambda {
    
    public static void main(String[] args) {
        List<Account> bunchOfAccount = new ArrayList<>();
    
        Account accountOfZhangSan = new Account(UUID.randomUUID().toString(), "张三", GenderEnum.男);
    
        Account accountOfLiSi = new Account(UUID.randomUUID().toString(), "王五", GenderEnum.男);
    
        Account accountOfZhangXin = new Account(UUID.randomUUID().toString(), "张馨", GenderEnum.女);
    
        bunchOfAccount.add(accountOfZhangSan);
        bunchOfAccount.add(accountOfLiSi);
        bunchOfAccount.add(accountOfZhangXin);
    
        // JDK1.5-foreach遍历
        for (Account account : bunchOfAccount) {
            System.out.println(account.getId());
            System.out.println(account.getName());
            System.out.println(account.getGender().name());
        }
        // for遍历
        for (int i = 0; i < bunchOfAccount.size(); i++) {
            Account currentAccount = bunchOfAccount.get(i);
            System.out.println(currentAccount.getId());
            System.out.println(currentAccount.getName());
            System.out.println(currentAccount.getGender().name());
        }
        // iterator迭代
        Iterator<Account> iteratorOfAccount = bunchOfAccount.iterator();
        while (iteratorOfAccount.hasNext()) {
            Account currentAccount = iteratorOfAccount.next();
            System.out.println(currentAccount.getId());
            System.out.println(currentAccount.getName());
            System.out.println(currentAccount.getGender().name());
        }
    }
}

2、使用Lambda表达式来遍历该集合

public class Java8OfLambda {

    public static void main(String[] args) {
        List<Account> bunchOfAccount = new ArrayList<>();

        Account accountOfZhangSan = new Account(UUID.randomUUID().toString(), "张三", GenderEnum.男);

        Account accountOfLiSi = new Account(UUID.randomUUID().toString(), "王五", GenderEnum.男);

        Account accountOfZhangXin = new Account(UUID.randomUUID().toString(), "张馨", GenderEnum.女);

        bunchOfAccount.add(accountOfZhangSan);
        bunchOfAccount.add(accountOfLiSi);
        bunchOfAccount.add(accountOfZhangXin);

        // Lambda写法
        bunchOfAccount.forEach(account -> {
            System.out.println(account.getId());
            System.out.println(account.getName());
            System.out.println(account.getGender().name());
        });
    }
}

解释:

(1)List集合的forEach方法也是继Java8之后的新方法,基于Lambda实现。

(2)Lambda的通用写法:(param) -> {}

(3)Lambda函数式接口(位于java.util.function包下)-- 参数讲解:(param) -> {}

<1>、 如果该Lambda接口没有参数必须要使用()来占位,例如:() -> {}

<2>、 有且仅有一个参数,在传递参数时,可以省略括号(),例如:param -> {}

<3>、有多个参数,在传递参数时,必须添加括号(),例如:(param1, param2, param3) -> {}

(4)Lambda函数式接口(位于java.util.function包下)-- 方法讲解:(param) -> {}

<1>、如果该Lambda接口需要传递的方法体只有一行代码,可以省略{},例如:(param) -> System.out.println("")

<2>、如果该Lamdba接口需要传递的方法体包含多行代码,必须要添加{},例如:(param) -> { int a = 1; int b = 2; }

<3>、注:如果包含多行代码,添加了{},一定要注意该Lamdba接口是否存在返回值,有则使用return返回值,否则无法通过编译!

四、Lambda函数式接口讲解---针对Java语法

1、Java8更新的函数式接口都存在于java.util.function包下

function包是Java8新出的一个函数式接口管理包,内置所有都是Interface,上面的forEach方法的参数就是用的该包下的Consumer接口来实现集合的遍历,有兴趣的小伙伴可以看下forEach方法的源码!

2、函数式接口的特点

(1)函数式接口也是一个普通的接口,它的出现更是打破了Java对接口的定义

(2)Java在8之前对接口的定义是:

<1>、 所有的方法都必须是抽象方法,不能存在带方法体的方法;

<2>、 Java8以后的接口允许存在默认方法(default关键词实现)和静态方法(static关键词实现),这两种方法都可以存在方法体,不同的是默认方法(default修饰)只能由实现它的子类来调用,而静态方法(static修饰)只能由接口本身来调用。

(3)函数式接口规定只能存在一个抽象方法,不允许有两个或两个以上抽象方法,否则编译不通过!

(4)Java8为了在编写代码时检查接口是否为函数式接口,特更新了一个新的注解@FunctionInterface,作用域仅为接口,如果该接口使用@FunctionInterface注解标识,存在两个或以上抽象方法,会出现语法错误,无法通过语法检查!当然如果不使用该注解检查,只存在一个抽象方法,也是一个函数式接口。

(5)当然我们也可以自己定制符合业务的函数式接口,只需要存在一个抽象方法的接口,就是一个函数式接口了!

五、经验之谈---对Lamdba的理解

1、很多朋友会误解,认为Lambda表达式会提高代码运行效率,其实Lambda的仅仅是一种写法,对于Java开发者来说只是一种新型的语法,它的使用更不会提升代码的运行效率。只是为了使代码变得更加简洁,使用这种写法可以提高开发者的编码速度。

2、Java8中的新特性除了Lamdba表达式以外,还有基于Lambda的stream流,stream流是Oracle公司开发出的一个非常优秀的特性,它的出现可以解决很多性能问题,甚至包含了SQL的一些过滤筛选,排序的特性,在数据量大的情况下可以提高代码运行效率!Stream流会在一下章节会为大家详细讲解,学会了Stream可以解决很多问题,简化很多代码,强烈建议学习!

3、在平常工作中,使用到了很多Lambda表达式,不得不说这种写法非常优美,代码看起来也非常舒服!

六、个人对Lambda前景的感想

有很多朋友在平常开发中不用不到Lambda,觉得学了也没用,所以就不学了。我觉得这种写法是一种新型的写法,既然外面对Lamdba吵得沸沸扬扬,为什么我们不深入进去,学习一下呢?可能几年以后Lambda火起来了,你看到的每个项目中,大量使用到这种写法,那时候你才学吗?可能在几年以后,你感觉Java的语法自己都看不懂了,那时候你就快要跟Java说再见了!时代在进步,作为处于时代一线的我们如果技术跟不上时代的进步,那么总有一天会被淘汰掉!前段时间JDK12已经发布了,如果连JDK8中的新特性都不会用,就已经落后了(逆水行舟,不进则退)。如果当前的公司中没有用到这种写法,不代表跳槽到第二家公司,项目中没有这种写法,到时候再去请教同事吗?说到这里,可能有的朋友不喜欢听了,现实就是这样,技术人员是当今最容易被时代淘汰的职业之一。作为技术人员的我们,千万不要排斥任何一种新技术,只要有技术,就不怕随着时代的进步而被淘汰,就不怕多年后会失业!

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门