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

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、函数式接口举例

13909371-497b8d3aea2452ca.png

4、自定义函数式接口

@FunctionalInterface
interface MyNumber {
      public double getValue();
}

//函数式接口中使用泛型
@FunctionalInterface
interface MyFun<T> {
      public T getValue(T t);
}

5、作为参数传递 Lambda 表达式

13909371-aa1373497bab9fbc.png

13909371-ccc02e589209cd1e.png

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

6、Java 内置函数式接口

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

13909371-31581d6411bc0737.png

 

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

13909371-b4eaf96098b3071c.png

 

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值