Java8新特性-Lambda表达式(一)

Java8 Lambda表达式

Lambda表达式是所有Java8新特性中比较重要的特性,同时也是一些后续新特性的基础,比如在Stream特性中就大量运用了这一新特性,本篇文章主要是个人的一些理解和示例代码

什么是Lambda表达式

个人的理解是一种匿名函数的语法,在功能上与匿名函数一致。lambda表达式为匿名函数定义了更简洁灵活的语法

为什么需要Lambda表达式

下面我们会使用基于Lambda表达式的函数式编程与传统编程进行对比,体会这种做法的妙处

  • 需求:实现一个筛选学生的功能
  • 创建实体类Student
package entity;

public class Student {

    public Student() {
    }

    public Student(int id, int age, String name, int sex, int score) {
        this.id = id;
        this.age = age;
        this.name = name;
        this.sex = sex;
        this.score = score;
    }

    private int id ;
    private int age ;
    private String name ;
    private int sex ;
    private int score ;
    //getset 省略
    public boolean isFirstStudent(){
        return  1==this.getId();
    }
}
  • 如果你是一个有经验的程序员,你会对筛选这个功能做个抽象,然后根据业务不同的筛选逻辑分别实现接口,现在创建过滤接口
public interface StudentFilter {
    boolean filter (Student student);
}
  • 根据业务实现这个接口,比如根据年龄,又或者根据分数判断学生是否符合条件
public class SexFilter implements StudentFilter {
    @Override
    public boolean filter(Student student) {
        if(student.getSex() ==1){
            return true ;
        }
        return false;
    }
}


public class AgeFilter  implements StudentFilter {
    @Override
    public boolean filter(Student student) {
        if(student.getAge()>20){
            return true ;
        }
        return false;
    }
}
  • 下面是我们的主函数,根据不同的filter实现,获取学生的名字
public class OriMain {
    public static void main(String[] args) {
        List<Student> students = Arrays.asList(new Student(1,27,"wwh",1,99),
                new Student(2,25,"yuachen",1,68),
                new Student(3,29,"firstin",1,78),
                new Student(4,26,"bgirl",0,20),
                new Student(5,18,"sgirl",0,50));

        //根据年龄过滤出姓名列表
        List<String> names = getNameByFilter(students,new AgeFilter());

        //根据性别过滤出姓名列表
        List<String> name2 = getNameByFilter(students,new SexFilter());


    }


    private static List<String> getNameByFilter(List<Student> students, StudentFilter filter) {
        List<String> result = new ArrayList<>();
        for (Student stu : students) {
            String name = stu.getName();
            if(filter.filter(stu)){
                result.add(name);
            }
        }
        return result;
    }
}
  • 如果这时候我们又需要挑选出得分高于80分的学生姓名,我们又需要实现一遍接口,会使代码量很大,累很多,维护困难,或者你不想为了几行代码创建一个实现类,采用匿名内部类的形式如下。但是这种方式往往看上去很笨重啰嗦
        List<String> names = getNameByFilter(students, new StudentFilter() {
            @Override
            public boolean test(Student student) {
                return student.getScore()>80;
            }
        });

想要灵活试试Lambda表达式

从下面的代码量就可以感受到代码灵活了不少,语义也更加明确
public class LambdaDemo {

    public static void main(String[] args) {


        List<Student> students = Arrays.asList(new Student(1,27,"wwh",1,99),
                new Student(2,25,"yuachen",1,68),
                new Student(3,29,"firstin",1,78),
                new Student(4,26,"bgirl",0,20),
                new Student(5,18,"sgirl",0,50));
        //可以把Lambda表达式理解为简洁地表示可传递的匿名函数的一种方式
        List<String> nameList = getNameByLambda(students,(student)->student.getAge()>20);

        //获取id为一的学生姓名
        List<String> nameList2 = getNameByLambda(students,(student)->student.isFirstStudent());
        //方法引用
        List<String> nameList3 = getNameByLambda(students,Student::isFirstStudent);

        printStudentList(students);

    }



    /**
     *函数式接口:
     * 定义 函数式接口就是只定义一个抽象方法的接口
     * 注解 @FunctionalInterface
     *
     * Lambda表达式可以被赋给一个
     * 变量,或传递给一个接受函数式接口作为参数的方法就好了,当然这个Lambda表达式的签名要
     * 和函数式接口的抽象方法一样
     */
    private static List<String> getNameByLambda(List<Student> students, Predicate<Student> predicate) {
        List<String> result = new ArrayList<>();
        for (Student stu : students) {
            String name = stu.getName();
            if(predicate.test(stu)){
                result.add(name);
            }
        }
        return result;
    }

    //Stream API的使用,后续会介绍
    private static void printStudentList(List<Student> stringList) {
        stringList.stream().map(Student::getName).forEach(System.out::println);
    }

}

什么场景适合运用Lambda表达式让代码更灵活

public class LambdaDemo {

    public static void main(String[] args) {
        //场景一:线程创建
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("create thread");
            }
        });
        t.start();

        Thread t2 = new Thread(()->{
            System.out.println("createBy Lambda");
        });
        t2.start();

        //场景二:sort方法
        List<Student> students = Arrays.asList(new Student(1,27,"wwh",1,99),
                new Student(2,25,"yuachen",1,68),
                new Student(3,29,"firstin",1,78),
                new Student(4,26,"bgirl",0,20),
                new Student(5,18,"sgirl",0,50));

        //sort应用
        students.sort((a,b)->a.getAge()-b.getAge());

        //方法引用就是让你根据已有的方法实现来创建Lambda表达式
        students.sort(comparing(Student::getAge));

        //场景三:stream API中应用
        students.stream().map(Student::getName).forEach(System.out::println);

    }
}

java8提供的一些函数式接口

四大核心函数式接口:

  1. Predicate<T> : 断言型接口  定义了一个名叫test的抽象方法,它接受泛型T对象,并返回一个boolean
  2. Consumer<T> : 消费型接口  定义了一个名叫accept的抽象方法,它接受泛型T的对象,没有返回void
  3. Supplier<T>: 供给型接口  定义了一个名叫get的抽象方法,它不接受参数,并返回一个对象T
  4. Function<T,R> : 函数型接口  Function接口定义了一个叫作apply的方法,它接受一个泛型T的对象,并返回一个泛型R的对象

这里写图片描述
这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值