【Java8新特性】Lambda表达式

1.什么是Lambda表达式?

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

2.为什么要用Lambda表达式?

个人理解:因为简洁,节省代码

3.Lambda表达式用法:

  • 一、lambda表达式的基本语法:java8中引入了一个新的操作符“->”改操作符称为箭头操作符或lambda操作符
  • 箭头操作符将lambda表达式拆分成两部分
  • 左侧:lambda 表达式的参数列表
  • 右侧:lambda 表达式中所学执行的功能,即lambda体
  • 语法格式一:无参数,无返回值
    ()->System.out.println(“Hello Lambda!”);
  • 语法格式二:有一个参数,并且无返回值
    (x)->System.out.println(“Hello Lambda!”);
  • 语法格式三:若只有一个参数,()可以省略不写
    x->System.out.println(“Hello Lambda!”);
  • 语法格式四:有两个以上的参数,有返回值, 并且lambda体中有多条语句
  • 语法格式五:若lambda体中只有一条语句,return和{}都可以省略不写
  • 语法格式六:lambda表达式的参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出,数据类型,即“类型推断”
    (x , y) -> Integer.compare(x, y);
  • 二:lambda表达式需要“函数式接口”的支持
  • 函数式接口:接口只有一个抽象方法的接口,成为函数式接口可以使用注解@FunctionalInterface

4.Lambda表达式应用和对比

假设,我们现在有一个需求:获取当前公司中员工年龄大于35的员工信息

员工的信息:

    List<Employee> employees = Arrays.asList(
            new Employee("1", 18, 9999.99),
            new Employee("2", 25, 6666.99),
            new Employee("3", 12, 33333.99),
            new Employee("4", 68, 3333.99),
            new Employee("5", 8, 77777.99)
            );

最一般的做法:写一个方法判断年龄,然后测试时传入员工信息

    public List<Employee> filterEmployees(List<Employee> list){
        List<Employee> emps =new ArrayList<>();     
        for(Employee emp: list) {
            if (emp.getAge()>12) {
                emps.add(emp);
            }
        }
        return emps;
    }
@Test
    public void test3() {
        List<Employee> list = filterEmployees(employees);

        for(Employee employee :list) {
            System.out.println(employee.getAge());
        }
    }

但是现在有心的需求,获取当前公司中员工工资大于5000的员工信息,这时候就需要再写一个方法来判断薪资

public List<Employee> filterEmployees2(List<Employee> list){
        List<Employee> emps =new ArrayList<>();

        for(Employee emp: list) {
            if (emp.getSalary()>5000) {
                emps.add(emp);
            }
        }
        return emps;
    }

缺点:如果再添加其他需求,还需要添加新的方法,这样就产生了大量冗余。

优化方法一:策略模式

创建一个接口供方法调用实现

public interface MyPredicate<T> {

    public boolean test(T t);
}

用方法来实现接口

public List<Employee> filterEmployee(List<Employee> list, MyPredicate<Employee> mp){
        List<Employee> employees= new ArrayList<>();

        for(Employee employee :list) {
            if (mp.test(employee) ) {
                employees.add(employee);
            } 
        }
        return employees;
    }

调用写好的方法

@Test
    public void test4() {
        List<Employee> list = filterEmployee(employees,new FilterEmployeeByAge());

        for(Employee employee : list) {
            System.out.println(employee.getAge());  
        }
    }

缺点:当添加新的需求,则需要添加新的接口

优化方式二:匿名内部类

    @Test
    public void test05() {
        List<Employee> list = filterEmployee(employees, new MyPredicate<Employee>() {

            @Override
            public boolean test(Employee t) {

                return t.getSalary()<=5000;
            }
        });

        for(Employee employee :list) {
             System.out.println(employee);
        }

    }

优化方式三:Lambda表达式

@Test
    public void test6() {
        List<Employee> list = filterEmployee(employees, (e) -> e.getSalary()>=3000 );
        list.forEach(System.out::println);  
    }

两句话就解决了的问题,很简洁有木有啊!
lambda表达式中传入的employees相当于方法一中MyPredicate接口传进的 t 变量, (e) -> e.getSalary()>=3000 就相当于MyPredicate接口的实现。

猜你喜欢

转载自blog.csdn.net/zjy15203167987/article/details/80037375