Fork me on GitHub

JDK8新特性:函数式接口

一,定义

函数式接口,英文为Functional Interface。首先它是一个接口,那么它与其它接口有什么不同呢?不同点就是在这个接口中只允许有一个抽象方法。

这里的只允许一个抽象方法不包括以下几种情况:
1,函数式接口里面允许有默认方法。我觉得可能是java设计师考虑到默认方法不是抽象的,它有默认实现的方法体。

2,函数式接口里面允许有静态方法。原因和上面相同,静态方法并不能是抽象方法。

3,函数式接口里面允许有java.lang.Object的public方法。可能是因为接口的实现类都继承了java.lang.Object。

package com.czx;

//该注释是在编译期间检查是否为函数式接口
@FunctionalInterface
public interface JDK8Interface {
    
    //抽象方法
    public boolean isNull(Object o);
    
    //java.lang.Object中public方法
    public boolean equals(Object obj);
    public int hashCode();
    
    //static方法
    public static void staticMethod(){
        System.out.println("JDK8Interface的静态方法");
    }
    
    //default方法
    public default void defaultMethod(){
        System.out.println("JDK8Interface的默认方法");
    }
}

注意:如果你想定义一个函数式接口的话,最好把@FunctionalInterface加上,它会在编译期间检测该接口是否为函数式接口。

二,运用

我们可以通过Lambda表达式实现接口的抽象方法,比之前简直简洁太多。之前的方法是写一个实现该接口的类,并写出实现体。具体的不写了,我们看看通过Lambda表达式的代码有多简洁。

 

package com.czx;

public class Test2 {

    public static void main(String[] args) {
        JDK8Interface it = (a) -> a == null;
        
        System.out.println(it.isNull(2));//false
        System.out.println(it.isNull("mine"));//false
        System.out.println(it.isNull(null));//true
    }
}

 

这就结束了,是不是很简单。

 

三,JDK8中新增的函数式接口

JDK8中引入了java.util.function,此包中内置许多函数式接口,现在将几个常用的函数式接口做说明。

 

 

 

1,Predicate接口

输入一个参数,并返回一个Boolean值,其中内置许多用于逻辑判断的默认方法:

    @Test
    public void predicateTest() {
        Predicate<Integer> predicate = (s) -> s > 0;
        boolean test = predicate.test(2);
        System.out.println("该数字大于0:" + test);

        test = predicate.test(0);
        System.out.println("该数字大于0:" + test);

        test = predicate.negate().test(0);
        System.out.println("该数字小于等于0:" + test);
    }

2,Function接口

接收一个参数,返回单一的结果,默认的方法(andThen)可将多个函数串在一起,形成复合Funtion(有输入,有输出)结果:

    @Test
    public  void functionTest() {

        Function<Integer, Integer> add = (i) -> {
            System.out.println("初始值:" + i);
            return i+1;
        };
        Function<Integer, Integer> power = add.andThen((i) -> {
            System.out.println("第一次运算:" + i);
            return i * i;
        });

        Integer res = power.apply(2);
        System.out.println("第二次运算:" + res);
    }

3,Supplier接口

返回一个给定类型的结果,与Function不同的是,Supplier不需要接受参数(供应者,有输出无输入):

    @Test
    public void supplierTest() {
        Supplier<String> supplier = () -> "有输出,无输入。";
        String s = supplier.get();
        System.out.println(s);
    }

4,Consumer接口

代表了在单一的输入参数上需要进行的操作。和Function不同的是,Consumer没有返回值(消费者,有输入,无输出):

    @Test
    public void consumerTest() {
        Consumer<Integer> add = (p) -> {
            System.out.println("old value:" + p);
            p = p + 1;
            System.out.println("new value:" + p);
        };
        add.accept(1);
    }

以上四个接口的用法代表了java.util.function包中四种类型,理解这四个函数式接口之后,其他的接口也就容易理解了。

posted @ 2018-04-08 19:43  爱跑步的星仔  阅读(902)  评论(0编辑  收藏  举报