JDK8新特性-函数式接口

首言:

函数式编程作为一种编程范式,在科学领域,是一种编写计算机程序数据结构和元素的方式,它把计算过程当做是数学函数的求值,而避免更改状态和可变数据。而Java中的函数式编程体现就是Lambda,所以函数式接口就是可以适用于Lambda使用的接口。只有确保接口中有且仅有一个抽象方法,Java中的Lambda才能顺利地进行推导。

 一、函数式接口

特点

  • 接口有且仅有一个抽象方法
  • 允许定义静态方法
  • 允许定义默认方法
  • 允许java.lang.Object中的public方法
  • 注解@FunctionInterface不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错

基于以上函数式接口特点,可以想到Runnable接口就是一个最典型的函数式接口。接口中只有一个run抽像方法。JDK8中查看Runnable源码,可以看到在接口上加上了@FunctionInterface注解,标识此接口为函数式接口。

@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();

二、内置函数式接口

lambda表达式实例化该接口,达到简化写法的目的。在JDK8中内置了四个核心的函数式接口来适用我们通用编程需要。

函数式接口方法参数类型返回类型作用
Consumer<T> 消费型接口void accept(T t)Tvoid对T类型的参数进行操作
Supplier<T> 供给型接口T get()T操作数据,返回T类型的结果
Function<T, R> 函数型接口R apply(T t)TR对T类型参数进行操作,并返回R类型的结果
Predicate<T> 断定型接口boolean test(T t)Tboolean确定T类型参数是否满足某约束,并返回boolean值

1、Consumer消费型接口

该接口提供一个accept方法,接受一个参数,无返回值。

@FunctionalInterface
public interface Consumer<T> {
    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);

 我们看个例子,定义了一个lambda实现体,通过accept传入参数,打印传入的参数信息

@Test
public void test() {
    String str = "伴学编程";
    Consumer consumer = t -> System.out.println(t);
    consumer.accept(str);
}

2、Function函数型接口

该接口提供一个apply方法,接受一个参数,有返回值。

@FunctionalInterface
public interface Function<T, R> {
    /**
     * Applies this function to the given argument.
     *
     * @param t the function argument
     * @return the function result
     */
    R apply(T t);

我们看个例子,定义了一个lambda实现体,通过apply方法传入参数,打印传入的参数信息。

@Test
public void test() {
    String str = "伴学编程";
    Function function = t -> t;
    System.out.println(function.apply(str));
}

3、Supplier供给型接口

该接口提供一个get方法,无参数,有返回值。

@FunctionalInterface
public interface Supplier<T> {
    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}

我们看个例子,定义了一个lambda实现体,通过get方法返回并打印返回信息。 

@Test
public void test() {
    String str = "伴学编程";
    Supplier supplier = () -> str;
    System.out.println(supplier.get());
}

4、Predicate断言型接口

该接口提供一个test方法,传入一个参数,返回boolean型值。 

@FunctionalInterface
public interface Predicate<T> {
    /**
     * Evaluates this predicate on the given argument.
     *
     * @param t the input argument
     * @return {@code true} if the input argument matches the predicate,
     * otherwise {@code false}
     */
    boolean test(T t);

我们看个例子,定义了一个lambda实现体,通过test方法传入参数,返回并打印判断结果。 

@Test
public void test() {
    String str = "伴学编程";
    Predicate predicate = t -> "伴学编程".equals(t);
    System.out.println(predicate.test(str));
}

上面是通用比较典型的接口,有同伴可能需要一个函数式接口操作两个参数,并有返回值。JDK8也内置这些子接口。

函数式接口方法参数类型返回类型作用
BiFunction<T , U, R >R apply(T t, U u)T, UR对 T, U 类型的参数进行操作,并返回R类型的结果
UnaryOperator<T> (Function 子接口)T apply(T t)TT对 T类型的参数进行一元运算,并返回R对象的结果
BinaryOperato<T,R> (BiFunction 子接口) )T apply(T t1, T t2)T, TT对T类型的参数进行二元运算,并返回T类型的结果
BiConsumer<T, U>void accept(T t, U u)T, Uvoid对T,作
ToIntToIntFunction<T> ToLongFunction<T> ToDoubleFunction<T>int(long,double) applyAsInt(T value)Tint, long, double计 算 int 、 long 、double值的函数
IntFunction<R> LongFunction<R> DoubleFunction<R>R apply(int(long,double) value)int, long, doubleR参数分别为int、long、double 类型的函数

三、默认方法、静态方法

JDK7中,接口能定义全局静态属性与抽像方法。JDK8的接口现在可以定义默认方法与静态方法。

1、默认方法

简单说,默认方法就是接口可以有实现方法,而且不需要实现类去实现其方法。

我们只需在方法名前面加个 default 关键字即可实现默认方法。

@FunctionalInterface
public interface LambdaService {
    boolean isAvailable(String name, Integer age);
    
    default String getName() {
        return "伴学编程";
    }
}

2、静态方法

Java 8 的另一个特性是接口可以声明静态方法,在方法返回类型前加static关键字即可实现静态方法。

@FunctionalInterface
public interface LambdaService {
    boolean isAvailable(String name, Integer age);
    static String getName() {
        return "伴学编程";
    }
}

四、小结

JAVA 8 之前接口定义的抽像方法一般是用匿名类实现的,JDK8就可以使用Lambda表达式来表示该接口的一个实现,而函数式接口可以对现友好地支持lambda表达式,将函数参数形式传入方法中,使用代码编程简洁、优雅。

扫描下方二维码,关注微信公众号,掌握最新动态。与关注的同伴们一起学习,一起编程!

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值