Lambda表达式到底是什么?——简单了解Lambda表达式

一、Lambda表达式是什么

简单来说,Lambda表达式是一个可传递的代码段。可以不借助对象传递的一个代码段。那java作为一个面向对象的语言,为什么要加入这么一个特性呢?

二、为什么使用Lambda表达式

从一个简单的例子开始。
比如现在有一个Person类

package POJO;

import lombok.Data;
import java.util.Objects;

/**
 * @author wangtianqi
 * @create 2020-08-19 15:59
 */
@Data
public class Person {
    private String name;
    private Integer age;
    private String country;
    private char sex;
}

如果不使用Lambda表达式将下面这个Person集合中的元素按照年龄从小到大排序。

List<Person> personList = new ArrayList<>();
        //personList.add(new Person("欧阳霜",18,"中国",'F'));
        personList.add(new Person("欧阳雪", 18, "中国", 'F'));
        personList.add(new Person("Tom", 24, "美国", 'M'));
        personList.add(new Person("Harley", 22, "英国", 'F'));
        personList.add(new Person("向天笑", 23, "中国", 'M'));
        personList.add(new Person("李康", 22, "中国", 'M'));
        personList.add(new Person("小梅", 20, "中国", 'F'));
        personList.add(new Person("何雪", 21, "中国", 'F'));
        personList.add(new Person("李康", 22, "中国", 'M'));

很自然的可以想到,使用工具类Collections中的sort方法。sort方法需要提供一个Comparator接口的实现类。

package POJO;

import java.util.Comparator;

/**
 * @author wangtianqi
 * @create 2020-09-08 10:03
 */
public class ComparePerson implements Comparator<Person> {

    @Override
    public int compare(Person p1, Person p2) {
        return p1.getAge() - p2.getAge();
    }
}

然后使用sort方法将集合排序。

/**
 * lambda表达式相关
 *
 * @author wangtianqi
 * @create 2020-09-08 10:05
 */
public class Test3 {

    public static void main(String[] args) {

        List<Person> personList = new ArrayList<>();
        //personList.add(new Person("欧阳霜",18,"中国",'F'));
        personList.add(new Person("欧阳雪", 18, "中国", 'F'));
        personList.add(new Person("Tom", 24, "美国", 'M'));
        personList.add(new Person("Harley", 22, "英国", 'F'));
        personList.add(new Person("向天笑", 23, "中国", 'M'));
        personList.add(new Person("李康", 22, "中国", 'M'));
        personList.add(new Person("小梅", 20, "中国", 'F'));
        personList.add(new Person("何雪", 21, "中国", 'F'));
        personList.add(new Person("李康", 22, "中国", 'M'));

        Collections.sort(personList,new ComparePerson());

		// 遍历打印
        for (Person person : personList) {
            System.out.println(person);
        }
    }
}

例子到这就结束了。再回过头看main方法中的Collections.sort(personList,new ComparePerson());这条语句。如果仅仅是看这条语句,并不能直观的了解到这个排序是按照哪个条件进行的。需要找到ComparePerson这个实现类,才能看到排序的条件。代码的可读性不高。并且提供实现类,也需要编写代码,代码不简洁
如果java支持函数式编程,就可以很好的解决这问题。例如ComparePerson类中只提供了一种方法。使用函数式编程,就不需要为了这个代码段编写一个类,直接在需要的地方编写一个代码段即可。
lambda表达式就是为了让java实现函数式编程而出现的。

三、Lambda表达式的语法

接着上面一节,这次我们使用Lambda表达式实现集合排序。

import POJO.ComparePerson;
import POJO.Person;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * lambda表达式相关
 *
 * @author wangtianqi
 * @create 2020-09-08 10:05
 */
public class Test3 {

    public static void main(String[] args) {

        List<Person> personList = new ArrayList<>();
        //personList.add(new Person("欧阳霜",18,"中国",'F'));
        personList.add(new Person("欧阳雪", 18, "中国", 'F'));
        personList.add(new Person("Tom", 24, "美国", 'M'));
        personList.add(new Person("Harley", 22, "英国", 'F'));
        personList.add(new Person("向天笑", 23, "中国", 'M'));
        personList.add(new Person("李康", 22, "中国", 'M'));
        personList.add(new Person("小梅", 20, "中国", 'F'));
        personList.add(new Person("何雪", 21, "中国", 'F'));
        personList.add(new Person("李康", 22, "中国", 'M'));

//        Collections.sort(personList,new ComparePerson());

        Collections.sort(personList, (p1, p2) -> p1.getAge() - p2.getAge());
        
        for (Person person : personList) {
            System.out.println(person);
        }
    }
}

我们使用非常简短的一个代码段完成了ComparePerson类提供的功能。代码更简洁。并且对比使用实现类的语句,这段代码可以很清楚的了解到这次排序是按照年龄进行的。可读性更好。

lambda表达式基本语法

  • Java8中引入了一个新的操作符,->,该操作符称为箭头操作符或者Lambda操作符,箭头操作符将Lambda表达式拆分成两部分;
  • 左侧: Lambda表达式的参数列表,对应的是接口中抽象方法的参数列表;
  • 右侧: Lambda表达式中所需要执行的功能(Lambda体),对应的是对抽象方法的实现;(函数式接口(只能有一个抽象方法))
  • Lambda表达式的实质是 对接口的实现;当接口只有一个方法(非静态方法,非默认方法)时,才可以使用lambda表达式。
四、函数式接口

上面提到了当接口只有一个方法(非静态方法,非默认方法)时,才可以使用lambda表达式。 在java中这种接口叫做,函数式接口。可以使用@FunctionalInterface注解来声明某个接口是一个函数式接口。
当在方法中的某个参数为函数式接口的引用时,在调用该方法时,就可以使用lambda表达式为该接口引用提供一个具体实现。

看一眼sort方法的源码,第二个参数Comparator<? super T> c是一个接口引用。

public static <T> void sort(List<T> list, Comparator<? super T> c) {
        list.sort(c);
    }

点进去看一眼,果然Comparator<T>是一个函数式接口。所以我们可以在使用sort方法时使用lambda表达式作为第二个参数。

@FunctionalInterface
public interface Comparator<T> {
五、Java中提供的四大函数式接口

如果你想要在自己的方法中添加函数式接口引用作为参数,Java提供了非常有代表性的四个函数式接口,我们只需要选择自己想要的接口即可。

四大函数式接口

  • Consumer< T >消费型 接口: void accept(T t);
    • 消费型接口Consumer,是一个有参数,但是无返回值类型的接口(void accept(T t);)
  • Supplier< T >供给型接口 : T get();
    • 供给型接口Supplier,是一个只有产出,没有输入,就是只有返回值,没有参数(T get();)
  • Function< T , R > 函数式接口 : R apply (T t);
    • 函数型接口Function<T,R>,是一个参数为T类型,返回值为R类型的接口(R apply(T t);)
  • Predicate< T > 断言型接口 : boolean test(T t);
    • 断言型接口Predicate,是一个参数为T类型,返回值为boolean类型的接口(boolean test(T t);)
六、总结

为何使用: 使用lambda表达式可以让代码的可读性更强,同时代码更简洁。但lambda的意义不仅仅于此,这里只是最显而易见的好处。
何时使用: 当调用的方法中的某个参数为函数式接口的引用时,就可以使用lambda表达式为该接口引用提供一个具体实现。
实质: 接口的具体实现。只不过不需要单独编写类。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值