美文网首页代码记忆
黑猴子的家:Java 8 -> 函数式接口

黑猴子的家:Java 8 -> 函数式接口

作者: 黑猴子的家 | 来源:发表于2019-03-02 06:03 被阅读65次
    1、什么是函数式(Functional)接口?

    (1)只包含一个抽象方法的接口,称为函数式接口

    (2)你可以通过 Lambda 表达式来创建该接口的对象。(若 Lambda 表达式抛出一个受检异常(即:非运行时异常),那么该异常需要在目标接口的抽象方法上进行声明)

    (3)我们可以在一个接口上使用 @FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口。同时 java doc 也会包含一条声明,说明这个接口是一个函数式接口

    (4)在java.util.function包下定义了java 8 的丰富的函数式接口

    判断是否是函数式接口

    @FunctionalInterface
    interface I1 {
          void play(String str);
    }
    
    //判断是否是函数式接口
    @FunctionalInterface
    interface I4 {
          void start();
          void stop();
    }
    
    2、如何理解函数式接口?

    (1)Java从诞生日起就是一直倡导“一切皆对象”,在java里面面向对象(OOP)编程是一切。但是随着python、scala等语言的兴起和新技术的挑战,java不得不做出调整以便支持更加广泛的技术要求,也即java不但可以支持OOP还可以支持OOF(面向函数编程)

    (2)在函数式编程语言当中,函数被当做一等公民对待。在将函数作为一等公民的编程语言中,Lambda表达式的类型是函数。但是在Java8中,有所不同。在Java8中,Lambda表达式是对象,而不是函数,它们必须依附于一类特别的对象类型——函数式接口

    (3)简单的说,在Java8中,Lambda表达式就是一个函数式接口的实例。这就是Lambda表达式和函数式接口的关系。也就是说,只要一个对象是函数式接口的实例,那么该对象就可以用Lambda表达式来表示。 所以以前用匿名内部类表示的现在都可以用Lambda表达式来写

    3、函数式接口举例
    4、自定义函数式接口
    @FunctionalInterface
    interface MyNumber {
          public double getValue();
    }
    
    //函数式接口中使用泛型
    @FunctionalInterface
    interface MyFun<T> {
          public T getValue(T t);
    }
    
    5、作为参数传递 Lambda 表达式

    作为参数传递 Lambda 表达式:为了将 Lambda 表达式作为参数传递,接收Lambda 表达式的参数类型必须是与该 Lambda 表达式兼容的函数式接口的类型。

    6、Java 内置函数式接口

    (1)Java 内置四大核心函数式接口(常用且重要

    (2)其他接口(不用掌握,感兴趣可以自己做测试

    7、函数式接口案例

    (1)Consumer<T> :消费性接口

    package com.yinggu.demo3;
    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;
    import org.junit.Test;
    import com.yinggu.data.EmployeeData;
    import com.yinggu.domain.Employee;
    
     * @author 黑猴子的家
     * http://www.121ugrow.com/
     * 此类用于演示函数式接口的使用 函数式接口:
     * 里面只有一个抽象方法的接口称为函数式接口
     * 只有函数式接口,才可以使用Lambda表达式生成对象
     * Consumer<T> :消费性接口     有参数  无返回
     * Supplier<T> :供给型接口     无参数  有返回
     * Function<T,R>:函数型接口   有参数  有返回
     * Predicate<T> :断定型接口   有参数  有返回(true 或  false)
    
    public class TestFunctionalInterface {
          
          /**
           * Consumer<T> :消费性接口     有参数  无返回
           */
          @Test
          public void testConsumer() {
                Consumer<Double> con = money -> {
                      if (money > 1000)
                            System.out.println("去k歌");
                      else if (money > 500)
                            System.out.println("去泡澡");
                      else
                            System.out.println("麻辣烫");
                };
                con.accept(580.0);
          }
    }
    

    (2)Supplier<T> :供给型接口 无参数有返回

    /**
     * Supplier<T> :供给型接口     无参数  有返回
     */
    @Test
    public void testSupplier() {
          Supplier<String> sup = () -> "苍老师".substring(0, 1);
          System.out.println(sup.get());
    }
    

    (3)Function<T,R>:函数型接口-有参数有返回

    方式一

    /**
     * Function<T,R>:函数型接口   有参数  有返回
     */
    @Test
    public void testFunction1() {
          Function<String, Integer> fun = str -> str.length();
          System.out.println(fun.apply("迪丽热巴"));
    }
    

    方式二

    /**
     * Function<T,R>:函数型接口   有参数  有返回
     */
    @Test
    public void testFunction2() {
          // 根据编号返回员工对象
          /*
           * 参数:int id——》Integer 返回:employee对象——》Employee
           */
          Function<Integer, Employee> fun = id -> {
                // 查找员工对象的步骤
                List<Employee> list = EmployeeData.getData();
                for (Employee employee : list) {
                      if (id == employee.getId()) {
                            return employee;
                      }
                }
                return null;
          };
          System.out.println(fun.apply(5));
    }
    

    (4)Predicate<T> :断定型接口-有参数有返回(true或false)

    方式一

    /**
     *  Predicate<T> :断定型接口   有参数  有返回(true 或  false)
     *  判断字符串的长度是不是3
     */
    @Test
    public void testPredicate() {
          Predicate<String> pre = str -> str.length() == 3;
          System.out.println(pre.test("段誉"));
    }
    

    方式二

    /**
     *  Predicate<T> :断定型接口   有参数  有返回(true 或  false)
     *  求满足条件的员工信息
     */
    @Test
    public void testPredicate2() {
          List<Employee> list = EmployeeData.getData();
          // 1.需求1:过滤年龄大于30岁
          List<Employee> data1 = getData(list, emp -> emp.getAge() > 30);
          for (Employee employee : data1) {
                System.out.println(employee);
          }
          System.out.println("-------------");
          // 2.需求2:过滤工资>20000
          List<Employee> data2 = getData(list, emp -> emp.getSalary() > 20000);
          for (Employee employee : data2) {
                System.out.println(employee);
          }
    }
    
    //定义一个方法
    public List<Employee> getData(List<Employee> list, Predicate<Employee> pre) {
          List<Employee> data = new ArrayList<>();
          for (Employee employee : list) {
                if (pre.test(employee)) {
                      data.add(employee);
                }
          }
          return data;
    }
    

    相关文章

      网友评论

        本文标题:黑猴子的家:Java 8 -> 函数式接口

        本文链接:https://www.haomeiwen.com/subject/offjuqtx.html