lambda表达式 2021-11-24 10:32 > 草稿版,以后会修改的 ### 一、定义: lambda表达式是一个匿名函数,是一段可以传递的代码。 函数式编程,意味着把函数作为值。函数式接口,使用 **@FunctionalInterface** 注解。被**@FunctionalInterface** 注解的接口只能有一个抽象方法。 > @FunctionalInterface不是必须的。没有@FunctionalInterface之后,如果你的接口有多个抽象方法,那么将无法进行lambda表达式编程,直接报错。 ### 二、组成: 参数列表 -> 函数体 () -> {...} 参数列表: - 1、可以省略参数类型,jdk会自己判断类型。 - 2、只有一个参数时,可以省略小括号()。 函数体: - 1、只有一条语句时,可以省略花括号{},或者写成小括号()。 ```java @FunctionalInterface interface MyFun { Integer fun1(Integer num); } ``` ```java MyFun myFun1 = a -> ++a; MyFun myFun2 = a -> {a++;a--; return a;}; MyCon myCon1 = (a, b) -> { System.out.println(b); return ++a; }; MyCon myCon2 = (a, b) -> a + Integer.parseInt(b); ``` ### 三、使用 JDK提供了四个最常用的函数式接口,基本大多数情况都能使用这四种。没提到的情况可以自己写新的函数式接口。 1、Function 接收一个参数类型 T , 返回类型 R ,适用于包装、修改等操作 R apply(T t); ```java @Data @AllArgsConstructor class Student { private String name; private Integer age; } package com.ppdai.ddp.third.maas5g.common.util; import lombok.AllArgsConstructor; import lombok.Data; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; @Data @AllArgsConstructor class Student { private String name; private Integer age; } /** * 输出学生名字 */ public class Test{ public static void main(String[] args) { Student student1 = new Student("a",11); Student student2 = new Student("b",12); Student student3 = new Student("c",21); Student student4 = new Student("d",1); List<Student> students = new ArrayList<>(); students.add(student1); students.add(student2); students.add(student3); students.add(student4); // List<String> names = filterStudent(students); //这里的 (e) -> e.getName() 是Function接口内apply函数的实现 List<String> names = filterStudent(students, (e) -> e.getName()); names.forEach((a) -> { a = a + "1"; System.out.println(a); }); /* a1 b1 c1 d1 */ } //普通方式 public static List<String> filterStudent(List<Student> list) { ArrayList<String> resultList = new ArrayList<>(); for (Student student : list) { resultList.add(student.getName()); } return resultList; } //lambda方式 //T R 一个是入,一个是出。即我需要将T类型的东西,经过某种apply()处理,变成R类型给到我。 public static <T, R> List<R> filterStudent(List<T> list, Function<T, R> function) { List<R> names = new ArrayList<>(); for (T element : list) { //这里看起来好像就一个getName的区别,apply变成了getName,我们将getName的表达提前了。 names.add(function.apply(element)); } return names; } } ``` 2、Consumer 接收一个参数 类型T ,无返回值 ,适用于遍历等操作 foreach void accept(T t); ```java Consumer<String> consumer = (str) -> { str = str + "1"; System.out.println("do something" + str); }; consumer.accept("123"); //do something1231 ``` 3、Predicate 接受一个参数T ,返回boolean,适用于判断过滤等操作 boolean test(T t); ```java Predicate<Integer> predicate = (a) -> ( a == 1 ); System.out.println(predicate.test(123)); //false ``` 4、Supplier 无参数,返回一个结果 T get(); ```java Supplier supplier = () -> (1); System.out.println(supplier.get()); //1 ``` ### 四、历史 lambda是为了代替匿名内部类,简化书写。 ```java // JDK7 匿名内部类写法 new Thread(new Runnable(){// 接口名 @Override public void run(){// 方法名 System.out.println("Thread run()"); } }).start(); ``` 使用lambda后: ```java // JDK8 Lambda表达式写法 new Thread( () -> System.out.println("Thread run()")// 省略接口名和方法名 ).start(); ``` --END--
发表评论