java8中 lambda表达式

java8 lambda表达式

lambda是一个匿名函数,先用以下的具体例子对比下

1.匿名内部类

原始方法

import org.junit.Test;
public class TestLambda {

    @Test
    public void test1() {
        Comparator<Integer> comparator = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1,o2);
            }
        };

        TreeSet<Integer> ts = new TreeSet<>(comparator);
        
    }
}

lambda表达式优化

    @Test
    public void test2(){
        Comparator<Integer> comparator = (x,y)-> Integer.compare(x,y);
        TreeSet<Integer> treeSet = new TreeSet<>(comparator);
    }

1.1实际案例:

筛选出一个公司中年龄大于30的人
Employee 类

@Data
@AllArgsConstructor
public class Employee {
    private String name;
    private Integer age;
    private double salary;
}

1.1.1原始方法

测试方法

    @Test
    private void test3(){
        Comparator<Integer> comparator = (x,y)-> Integer.compare(x,y);
        TreeSet<Integer> treeSet = new TreeSet<>(comparator);

        List<Employee> employees = Arrays.asList(
                new Employee("张三",20,88.8),
                new Employee("李四",30,88.8),
                new Employee("王五",25,88.8),
                new Employee("赵六",35,88.8),
                new Employee("孙七",40,88.8)
        );
        List<Employee> result = filterByAge(employees);
        System.out.println(result);

    }
    //筛选方法
    public List<Employee> filterByAge(List<Employee> employees){
        List<Employee> result = new ArrayList<>();

        for (Employee em : employees) {
            if (em.getAge()>30){
                result.add(em);
            }
        }
        return result;
    }

如果有多个单独的条件筛选,这样就需要很多filterBy的方法,并且重复率很高

优化方式一:

1.1.2使用设计模式

定义接口

public interface MyPredicate<T> {
    public boolean test(T t);
}

实现接口

public class FilterEmployeeByAge implements MyPredicate<Employee> {
    @Override
    public boolean test(Employee employee) {
        return employee.getAge()>30;
    }
}

过滤方法

    public List<Employee> filter(List<Employee> employees,MyPredicate<Employee>mp){
        List<Employee> result = new ArrayList<>();
        for (Employee employee: employees) {
            if (mp.test(employee)){
                result.add(employee);
            }
        }
        return result;
    }

测试方法

    @Test
    public void test4(){
        List<Employee> employees = Arrays.asList(
                new Employee("张三",20,88.8),
                new Employee("李四",30,88.8),
                new Employee("王五",25,88.8),
                new Employee("赵六",35,88.8),
                new Employee("孙七",40,88.8)
        );
        List<Employee> result = filter(employees, new FilterEmployeeByAge());
        System.out.println(result);
    }

1.1.3基于设计模式使用匿名内部类

过滤方法

    public List<Employee> filter(List<Employee> employees,MyPredicate<Employee>mp){
        List<Employee> result = new ArrayList<>();
        for (Employee employee: employees) {
            if (mp.test(employee)){
                result.add(employee);
            }
        }
        return result;
    }

测试方法

    @Test
    public void test5(){
        List<Employee> employees = Arrays.asList(
                new Employee("张三",20,88.8),
                new Employee("李四",30,88.8),
                new Employee("王五",25,88.8),
                new Employee("赵六",35,88.8),
                new Employee("孙七",40,88.8)
        );
        List<Employee> result = filter(employees, new MyPredicate<Employee>() {
            @Override
            public boolean test(Employee employee) {
                return employee.getAge()>30;
            }
        });
        System.out.println(result);
    }

1.1.4lambda表达式优化

过滤方法

    public List<Employee> filter(List<Employee> employees,MyPredicate<Employee>mp){
        List<Employee> result = new ArrayList<>();
        for (Employee employee: employees) {
            if (mp.test(employee)){
                result.add(employee);
            }
        }
        return result;
    }

测试方法

    @Test
    public void test6(){
        List<Employee> employees = Arrays.asList(
                new Employee("张三",20,88.8),
                new Employee("李四",30,88.8),
                new Employee("王五",25,88.8),
                new Employee("赵六",35,88.8),
                new Employee("孙七",40,88.8)
        );
        List<Employee> result = filter(employees,(employee) ->employee.getAge()>30);
        System.out.println(result);
    }

1.1.5 使用stream流优化

不需要过滤方法

    @Test
    public void test7(){
        List<Employee> employees = Arrays.asList(
                new Employee("张三",20,88.8),
                new Employee("李四",30,88.8),
                new Employee("王五",25,88.8),
                new Employee("赵六",35,88.8),
                new Employee("孙七",40,88.8)
        );
        employees.stream()
                .filter((e)->e.getAge()>30)
                .forEach(System.out::println);
    }

2.表达式语法

-> lambda表达式操作符,将整个表达式分成两部分,左边的为参数列表,右边的为lambda体
使用同级别的变量时,变量默认时final修饰的

2.1语法格式一

无参数无返回值

lambda表达式时需要接口支持的,这里的接口只是做例子,对应无返回值无参数,不代表实际意义

    @Test
    public void test1() {
        Runnable r1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("hello");
            }
        };
        r1.run();
        System.out.println("********************");
        Runnable r2 = ()-> System.out.println("hello");
        r2.run();
    }

2.2 语法格式二

一个参数,无返回值

    @Test
    public void test2() {
        Consumer consumer = (e)-> System.out.println(e);
        consumer.accept("hello");
    }

Consumer接口是专门支持lambda表达式的函数式接口,具体表现为:
使用@FunctionalInterface注解,该接口只消费
在这里插入图片描述
主要的方法就是accept(),传入一个参数,无返回值
在这里插入图片描述

2.3语法格式三

有两个以上的参数,有返回值,并且有多条执行语句
执行语句需要使用大括号进行包裹

    @Test
    public void test3() {
        Comparator<Integer> comparator = (x,y)->{
            System.out.println("hello");
            return Integer.compare(x,y);
        };

        comparator.compare(3,5);
    }

Comparator也是函数式接口

2.4 语法格式四

如果参数只有一个,小括号可以不写,但习惯上都写

    @Test
    public void test2() {
        Consumer consumer = e-> System.out.println(e);
        consumer.accept("hello");
    }

2.5 语法格式五

lambda体只有一个语句,大括号和return可以都不写

    @Test
    public void test4() {
        Comparator<Integer> comparator = (x,y)->Integer.compare(x,y);
        comparator.compare(3,5);
    }

3.函数式接口

接口中只有一个抽象方法的接口,称为函数式接口,使用@FunctionalInterface注解可以检查该接口是不是函数式接口
java内置的四大函数式接口

3.1 Consumer消费型接口

void accept(T t)

    @Test
    public void test1(){
        consumer(10,(e)->{
            System.out.println("输入的是"+e);
        });
    }


    /**
     * 定义一个方法
     */
    private void consumer(Integer num , Consumer<Integer> consumer){
        consumer.accept(num);
    }

3.2 Supplier 供给型接口

T get()

    @Test
    public void test2(){
        List<Integer> getlist = getlist(10, () -> (int) (Math.random()*100));
        System.out.println(getlist);

    }
    private List<Integer> getlist(Integer num , Supplier<Integer> supplier){
        List<Integer> list = new ArrayList();
        for (int i = 0; i <num ; i++) {
            Integer integer = supplier.get();
            list.add(integer);
        }
        return list;
    }

3.3 Function 函数型接口

R accept(T t)

    @Test
    public void test3(){
        String lsdadasd = strHandler("lsdadasd", (str) -> str.toUpperCase());
        System.out.println(lsdadasd);

    }
    private String strHandler(String string , Function<String,String> function){
        return function.apply(string);
    }

3.4 Predicate 断定型接口

boolean test(T t)

    public void test4(){
        List<String> list =Arrays.asList("l1","li2","lis3","list4");
        List<String> result = strFilter(list, (str) -> str.length() > 3);
        System.out.println(result);

    }
    private List<String> strFilter(List<String> list , Predicate<String> predicate){
        List<String> result = new ArrayList<>();
        for (String str:list) {
            if (predicate.test(str)){
                result.add(str);
            }
        }
        return result;
    }

3.5 实现基础函数式接口的其他接口

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Guesshat/article/details/112728260