前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java 8新特性 -- 函数式接口

Java 8新特性 -- 函数式接口

作者头像
Java深度编程
发布2020-06-10 09:18:27
7870
发布2020-06-10 09:18:27
举报
文章被收录于专栏:Java深度编程Java深度编程

JDK1.8提供一种特殊的接口 -- 函数式接口(Functional Interface),它与普通接口相比,就是比普通的接口多了一个方法。 函数式接口可以被隐式转换为lambda表达式。函数式接口现有的函数可以友好地支持 lambda。

其实早在JDK 1.8之前就已经有了一些函数式接口,如下:

  • java.lang.Runnable
  • java.util.concurrent.Callable
  • java.security.PrivilegedAction
  • java.util.Comparator
  • java.io.FileFilter
  • java.nio.file.PathMatcher
  • java.lang.reflect.InvocationHandler
  • java.beans.PropertyChangeListener 等

JDK 1.8 版本新增加的函数接口:

  • java.util.function

java.util.function 可以用来支持 Java的 函数式编程,该包中的函数式接口有:

序号

接口 & 描述

1

BiConsumer<T,U>代表了一个接受两个输入参数的操作,并且不返回任何结果

2

BiFunction<T,U,R>代表了一个接受两个输入参数的方法,并且返回一个结果

3

BinaryOperator<T>代表了一个作用于于两个同类型操作符的操作,并且返回了操作符同类型的结果

4

BiPredicate<T,U>代表了一个两个参数的boolean值方法

5

BooleanSupplier代表了boolean值结果的提供方

6

Consumer<T>代表了接受一个输入参数并且无返回的操作

7

DoubleBinaryOperator代表了作用于两个double值操作符的操作,并且返回了一个double值的结果。

8

DoubleConsumer代表一个接受double值参数的操作,并且不返回结果。

9

DoubleFunction<R>代表接受一个double值参数的方法,并且返回结果

10

DoublePredicate代表一个拥有double值参数的boolean值方法

11

DoubleSupplier代表一个double值结构的提供方

12

DoubleToIntFunction接受一个double类型输入,返回一个int类型结果。

13

DoubleToLongFunction接受一个double类型输入,返回一个long类型结果

14

DoubleUnaryOperator接受一个参数同为类型double,返回值类型也为double 。

15

Function<T,R> 接受一个输入参数,返回一个结果。

16

IntBinaryOperator接受两个参数同为类型int,返回值类型也为int 。

17

IntConsumer接受一个int类型的输入参数,无返回值 。

18

IntFunction<R>接受一个int类型输入参数,返回一个结果 。

19

IntPredicate:接受一个int输入参数,返回一个布尔值的结果。

20

IntSupplier无参数,返回一个int类型结果。

21

IntToDoubleFunction接受一个int类型输入,返回一个double类型结果 。

22

IntToLongFunction接受一个int类型输入,返回一个long类型结果。

23

IntUnaryOperator接受一个参数同为类型int,返回值类型也为int 。

24

LongBinaryOperator接受两个参数同为类型long,返回值类型也为long。

25

LongConsumer接受一个long类型的输入参数,无返回值。

26

LongFunction<R>接受一个long类型输入参数,返回一个结果。

函数式接口实例

Predicate <T> 接口是一个函数式接口,它接受一个输入参数 T,返回一个布尔值结果。

该接口包含多种默认方法来将Predicate组合成其他复杂的逻辑(比如:与,或,非)。

该接口用于测试对象是 true 或 false。

我们可以通过以下实例(Java8FunctionTest.java)来了解函数式接口 Predicate <T> 的使用:

代码语言:javascript
复制
package com.wenxue.jdk8;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

/**
 * @className: FunctionTest
 * @Description: TODO 测试java1.8的函数式接口
 * @version: v1.9.3
 * @author: GONGWENXUE
 * @date: 2019/12/11 15:39
 */
public class Java8FunctionTest {

    /**
     * @Author GONGWENXUE
     * @Description //TODO 测试 Predicate<T>函数式接口,传入一个参数n,返回一个boolean结果。
     * @version: v1.9.3
     * @Date 15:50 2019/12/11
     * @Param 
     * @return 
     **/
    public static void testFun(List<Integer> list, Predicate<Integer> predicate) {
        for(Integer n: list) {
            //当真正执行函数接口对象的test(n)时,才具体的传入了n的值。
            // 前面的表达式( n-> n%2 == 0)是函数式接口test方法的实现逻辑。
            if(predicate.test(n)) {
                System.out.println(n + " ");
            }
        }
    }

    public static void main(String[] args) {

        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
        System.out.println("输出所有偶数:");

        // Predicate<Integer> predicate1 = n -> 运算表达式(n%2==0)
        // n 是传递到 Predicate 接口的 test 方法的一个参数
        // n%2==0:是test方法的实现逻辑,这里是使用Lam表达式实现了对象的创建与抽象方法的实现
        // 调用方法传入n-> n%2 == 0时就已经实现了函数接口的对象与test方法的重写
        // 然后调用test方法,test方法的重写逻辑,从而返回ture或者false
        // n-> n%2 == 0: 标识函数式接口的test方法需要按照“参数值是偶数”时才返回true.
        testFun(list, n-> n%2 == 0 );//2,4,6

        System.out.println("输出大于 3 的所有数字:");
        testFun(list, n-> n > 3 );//4,5,6
    }

}
自定义函数式接口:

1.先编写函数式接口:

代码语言:javascript
复制
package com.wenxue.jdk8;

/**
 * @className: MyFunctionalInterface
 * @Description: TODO 自定义函数式接口
 * @version: v1.9.3
 * @author: GONGWENXUE
 * @date: 2019/12/11 21:14
 */
@FunctionalInterface
public interface MyFunctionalInterface<T> {
    
    Integer test(T t, T t2);
    //函数式接口有且只有一个抽象方法,写多个时@FunctionalInterface会报错
    //Integer test2(T t, T t2);
}

2.创建接口对象,实现抽象方法:

代码语言:javascript
复制
 MyFunctionalInterface<Integer> myFunctionalInterface =  (n,n2) -> n + n2;

3.调用函数接口方法:

代码语言:javascript
复制
package com.wenxue.jdk8;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

/**
 * @className: FunctionTest
 * @Description: TODO 测试java1.8的函数式接口
 * @version: v1.9.3
 * @author: GONGWENXUE
 * @date: 2019/12/11 15:39
 */
public class Java8FunctionTest {

      public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3);
    //创建函数式接口对象, 实现test方法的逻辑为将两个参数相加后返回
        MyFunctionalInterface<Integer> myFunctionalInterface =  (n,n2) -> n + n2;
        //调用函数式接口方法,执行运算逻辑
        testMyFunctionalInterface(list, myFunctionalInterface);
    }
  
    public static void testMyFunctionalInterface(List<Integer> list, MyFunctionalInterface<Integer> myFunctionalInterface) {
        for(Integer n: list) {
            Integer result = myFunctionalInterface.test(n,n);
            System.out.println(result);//2,4,6
        }
    }

}
函数接口与普通接口的区别:
函数接口只能有一个抽象方法(不包括继承或重写的Object的方法),普通接口可以有多个抽象方法。
代码语言:javascript
复制
@FunctionalInterface
public interface MyFunctionalInterface<T> {

    Integer test(T t, T t2);
    //函数式接口有且只有一个抽象方法,写多个会报错
    //Integer test2(T t, T t2);

    @Override//这个equals方法是从Object继承下来的,这里只是表示重写,所以不算多余的额外的抽象接口
    boolean equals(Object obj);
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java深度编程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 函数式接口实例
    • 自定义函数式接口:
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档