02. Java8-四大核心函数式接口

x33g5p2x  于2021-12-18 转载在 其他  
字(3.4k)|赞(0)|评价(0)|浏览(482)

只包含一个抽象方法的接口,称为函数式接口. 函数式接口可以通过@FunctionalInterface 注解, 这样编译时会做检查, 同时使用javadoc 生成文档时,也会说明这是一个函数式接口. 通常我们并不需要创建函数式接口, Java8 提供了内置的四大核心函数式接口和一些常用的函数式接口. java8 的函数式接口都在 rt.jar:java.util.function.* 包中.

1. 四大核心函数式接口

接口类抽象方法签名接口描述
Predicateboolean test(T t)断言式接口(谓词接口), 接收一个T类型参数,返回布尔值
Function<T, R>R apply(T t)函数式接口, 接收一个T类型参数,返回R类型结果. T和R可以为同一类型
SupplierT get()供给型接口, 不接收参数,返回T类型结果.
Consumeraccept(T t)消费型接口, 接收一个T类型参数,不返回结果.

2. 函数式接口使用示例

使用函数式接口时,一定要确认函数式接口的入参和返回值, 然后选择合适的函数式接口. 使用函数式接口时的步骤如下:

  1. 定义方法时, 将函数式接口作为函数的一个参数. 可为具体类型或泛型
  2. 调用方法时, 将lambda 表达式传入
  3. 方法体中,通过调用函数时接口的抽象方法来执行lambda 表达式传入的代码.
  • 测试数据
static List<Employee> emps = new ArrayList<>();

static {

    emps.add(new Employee(1001, "张三", "Man", 50));
    emps.add(new Employee(1002, "李四", "Man", 30));
    emps.add(new Employee(1003, "王五", "Woman", 25));
    emps.add(new Employee(1004, "赵六", "Man", 35));
    emps.add(new Employee(1005, "小七", "Woman", 30));
    emps.add(new Employee(1006, "周八", "Man", 42));
}

2.1 Predicate

接收一个参数, 返回布尔型值. 通常用于判断或过滤方法中.

@Test
public void test_Predicate(){

    List<Employee> manList = filterEmployee(emps, (employee -> "Man".equals(employee.getSex())));
    System.out.println("男员工列表:" + manList);

    List<Employee> womanList = filterEmployee(emps, (employee -> "Woman".equals(employee.getSex())));
    System.out.println("女员工列表:" + womanList);

    List<Employee> oldList = filterEmployee(emps, (employee -> employee.getAge() >= 50));
    System.out.println("老员工列表:" + oldList);

}

// 过滤员工列表
private List<Employee> filterEmployee(List<Employee> emps, Predicate<Employee> predicate){
    List<Employee> list = new ArrayList<>();

    for (Employee emp : emps) {
        if(predicate.test(emp)){
            list.add(emp);
        }
    }
    return list;
}

2.2 Function

接收一个参数, 返回一个值. 通常用于获取映射关系.

@Test
public void test_Function(){

    List<String> nameList = getEmployeePropertyList(emps, Employee::getName);
    System.out.println("员工姓名列表:" + nameList);

    List<Integer> ageList = getEmployeePropertyList(emps, (employee -> employee.getAge()));
    System.out.println("员工年龄列表:" + ageList);
}

// 获取员工属性列表
private <R> List<R> getEmployeePropertyList(List<Employee> employees, Function<Employee, R> function){
    List<R> list = new ArrayList<>();
    for (Employee employee : employees) {
        list.add(function.apply(employee));
    }
    return list;
}

2.3 Supplier

不接收参数, 返回一个值.

@Test
public void test_supplier(){

    List<Integer> list = getRandomList(5, () -> (int) (Math.random() * 100));
    System.out.println("获取5个 int 型随机数:" + list);

    List<Double> list2 = getRandomList(5, () -> Math.random() * 1000);
    System.out.println("获取5个double型随机数:" + list2);
}

// 获取随机数.
private <T> List<T> getRandomList(int num, Supplier<T> supplier){

    List<T> list = new ArrayList<>();
    for(int i=0; i<num; i++){
        list.add(supplier.get());
    }
    return list;
}

2.4 Consumer

接收一个参数, 不返回值.

@Test
public void test_Consumer(){

    printEmployee(emps, (employee -> System.out.println("员工:" + employee.getName())));
    printEmployee(emps, (employee -> System.out.println("员工:" + employee.getName() + "," + employee.getAge())));
    printEmployee(emps, (employee -> System.out.println("员工:" + employee.getName() + "," + employee.getAge() + "," + employee.getSex())));

}

// 打印员工信息
private void printEmployee(List<Employee> emps, Consumer<Employee> consumer) {
    for (Employee emp : emps) {
        consumer.accept(emp);
    }
}

相关文章