Java8新特性——函数式接口

2023-12-23 21:46:41

目录

一、介绍

二、示例

(一)Consumer?

源码解析

测试示例?

(二)Comparator

(三)Predicate

三、应用

四、总结?


一、介绍

@FunctionalInterface是一种信息注解类型,用于指明接口类型声明成为Java语言规范定义的函数式接口。从概念上说,函数式接口只有一个抽象方法,因为默认方法有一个实现,所以他们不是抽象的。如果一个接口声明了一个抽象方法覆盖java.lang的一个公共方法,这也不计入接口的抽象方法计数,因为接口的任何实现都将有来自java.lang.Object或其他地方的实现。函数式接口的实例可以使用lambda表达式、方法引用或构造函数引用来创建。


二、示例

(一)Consumer<T>?

(消费者)表示一个接受单个输入参数并且不返回结果的操作。

源码解析

accept()方法接收一个参数,并对该参数执行特定的操作,没有返回值

addThen()方法接受一个consumer类型的对象,它将一个consumer对象与另一个consumer对象进行关联,该方法会返回一个新的consumer对象,它首先执行当前consumer的accept()方法,然后再执行传入的after consumer对象的accpet()方法。

@FunctionalInterface
public interface Consumer<T> {

    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);

    /**
     * Returns a composed {@code Consumer} that performs, in sequence, this
     * operation followed by the {@code after} operation. If performing either
     * operation throws an exception, it is relayed to the caller of the
     * composed operation.  If performing this operation throws an exception,
     * the {@code after} operation will not be performed.
     *
     * @param after the operation to perform after this operation
     * @return a composed {@code Consumer} that performs in sequence this
     * operation followed by the {@code after} operation
     * @throws NullPointerException if {@code after} is null
     */
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

测试示例?

public class ConsumerTest {
    public static void main(String[] args) {
        Consumer<String> printUpperCase = s -> System.out.println(s.toUpperCase());
        Consumer<String> printLength = s -> System.out.println(s.length());
        Consumer<String> combine = printUpperCase.andThen(printLength);
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Jim");
        names.forEach(printUpperCase);
        names.forEach(combine);
    }
}

(二)Comparator<T>

(比较器)compare方法是Comparator接口中的方法,它用于比较两个对象的大小。一般来说,如果第一个对象小于第二个对象,则返回负整数;如果第一个对象等于第二个对象,则返回零;如果第一个对象大于第二个对象,则返回正整数。

public class ComparatorTest {
    public static void main(String[] args) {
        // 自定义比较器,实现compare方法,比较规则是自然数降序排列
        CustomedComparator customedComparator = new CustomedComparator();
        List<Integer> list = Arrays.asList(5, 8, -2, 0, 10);
        list.sort(customedComparator);
        // forEach函数传入一个consumer对象,底层是加强for循环 + 调用accpet()
        list.forEach(ele -> System.out.println(ele));
    }
}

Comparator接口声明了函数式接口,但接口中声明了两个抽象方法,这显然不符合之前给的定义。首先我先验证是否注解允许多个抽象方法,验证得出声明此注解的接口只能有一个抽象方法。Comparator接口中声明了equals和compare两个抽象方法,?其中equals是Object类的公共方法,这里令我不解的是接口中equals方法是声明的抽象方法,但它却无需实现,这里需要注意一下。最后,声明函数式接口只有一个抽象方法这是肯定的。

(三)Predicate<T>

(断言)predicate<T>代表了一个接受一个参数并返回布尔值结果的判断条件。该接口中只有一个抽象方法test,用于对给定的参数进行判断,并返回一个布尔值。

public class PredicateTest {
    public static void main(String[] args) {
        Predicate<Integer> predicate = num -> num % 2 == 0;
        System.out.println(predicate.test(11));
        System.out.println(predicate.test(0));
    }
}

三、应用

  1. forEach方法,迭代器方法,参数是consumer对象。
  2. Arrays.sort()方法,传入comparator对象,自定义比较
  3. Stream流操作
  4. lambda表达式

四、总结?

? 函数式接口是JDK8的新特性,在函数式接口使用ambda表达式会使代码更加简洁,上述内容如果有错误的地方,希望大佬们可以指正。我一直在学习的路上,您的帮助使我收获更大!觉得对您有帮助的话,还请点赞支持!我也会不断更新文章!

文章来源:https://blog.csdn.net/zhj2003_/article/details/135173055
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。