函数式接口

162 阅读2分钟

函数式接口

原文链接:函数式接口 | 柳门竹巷 (zhbblog.top)

参考文章:深度解析之Java8-函数式接口 - 知乎 (zhihu.com)万字长文详解Java lambda表达式 (qq.com)

定义

函数式接口:有且只有一个抽象方法的接口。

@FunctionalInterface注解

Java 8中为函数式接口引入了一个新的注解:@FunctionalInterface 。该注解可用于一个接口的定义上,在接口上使用该注解,编译器将会强制检查该接口是否有且仅有一个抽象方法。但是该注解不是必须的,只要符合函数式接口的定义,那么这个接口就是函数式接口。

原生函数式接口

Function: 函数型接口

Function接口是一个转换类型的接口,用来根据一个类型的数据得到另一个类型的数据,T称为前置条件,R称为后置条件即有入参,有返回,其中T是入参,R是返回

@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
}

Predicate: 断言型接口

Predicate接口是一个判断型接口,可以看做Function接口的特例即有入参,有返回,凡是返回的类型固定为boolean

@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
}

Consumer: 消费型接口

Consumer接口是一个消费型接口,主要负责消费数据即有入参,无返回

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}

Supplier: 供给型接口

Supplier接口是一个获取型接口,与Consumer接口相反,主要负责产生数据即无入参,有返回

@FunctionalInterface
public interface Supplier<T> {
    T get();
}

示例

public class Main {
    public static void main(String[] args) {
        /** 函数型接口 */
        Function<String,Integer> function = s->{
            return s.length();
        };
        /** 断言型接口 */
        Predicate<String> predicate = s->{
            return s.length() <= Byte.MAX_VALUE;
        };
        /** 消费型接口 */
        Consumer<String> consumer = s -> {
            System.out.println(s);
        };
        /** 供给型接口 */
        Supplier<String> supplier = ()->{
            return "PigwantAcat";
        };

        System.out.println(function.apply("PigwantAcat"));
        System.out.println(predicate.test("PigwantAcat"));
        consumer.accept("PigwantAcat");
        System.out.println(supplier.get());
    }
}

// 控制台输出如下:
// 11
// true
// PigwantAcat
// PigwantAcat

默认方法和静态方法

Java 8中允许接口有静态方法和默认方法。

自定义的函数式接口

/**
 * 函数式接口中只能有一个抽象方法,可以有默认方法和静态方法
 */
@FunctionalInterface
interface MyFunctionInterface{

    /**
     * 可以有常量,默认是【pubic static final】
     */
    String NAME="测试";

    /**
     * 测试函数式接口
     */
    void myTest();

    /**
     * 测试默认方法
     */
    default void myDefaultTest(){
        System.out.println("可以有默认方法");
    }

    /**
     * 测试静态方法
     */
    static void myStaticTest(){
        System.out.println("可以有静态方法");
    }

    /**
     * 获取name的值
     * @return java.lang.String
     */
    static String getName(){
        return NAME;
    }
}

测试

public class Main {
    public static void main(String[] args) {
//        MyFunctionInterface myFunctionInterface = new MyFunctionInterface() {
//            @Override
//            public void myTest() {
//                System.out.println("测试:函数式接口  重写");
//            }
//        };
        MyFunctionInterface mfi = ()->{
            System.out.println("测试:函数式接口  lambda简化");
        };
        mfi.myTest();
        mfi.myDefaultTest();
        MyFunctionInterface.myStaticTest();
        System.out.println(MyFunctionInterface.NAME);
        System.out.println(MyFunctionInterface.getName());
    }
}

// 控制台输出如下:
// 测试:函数式接口  lambda简化
// 可以有默认方法
// 可以有静态方法
// 测试
// 测试