函数式接口

什么是函数式接口?

定义:有且仅有一个抽象方法,但可以有多个非抽象方法的接口。

在Java 8中,函数式接口被专门存放于java.util.function包内,并且该包下的所有接口都使用@FunctionalInterface注解进行标记,这是Java 8为了支持函数式编程而引入的一个新特性。

除了java.util.function包中的函数式接口外,其他包中也存在一些函数式接口(例如java.lang.Runnable),其中有些并没有使用 @FunctionalInterface注解进行标注。然而,只要符合函数式接口的定义,这些接口仍然可以被视为函数式接口,与是否有此注解无关。注解的作用仅仅是在编译时起到强制规范定义的作用,提示编译器检查接口是否仅包含一个抽象方法。

四大函数式接口

常见的四大函数式接口为:Function(函数型接口)、Predicate(断言型接口)、Consumer(消费型接口)与Supplier(供给型接口)。

Function(函数型接口)

接收一个参数并产生结果,其函数描述符为T -> R
@FunctionalInterface
public interface Function<T, R> {

    R apply(T t);

    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

    static <T> Function<T, T> identity() {
        return t -> t;
    }
}
public static void main(String[] args) {
    // 写法一
    Function<String, String> f1 = new Function<String, String>(){
        @Override
        public String apply(String x) {
            return x.toUpperCase();
         }
     };
     System.out.println(f1.apply("f1 hello"));

     // 写法二
     Function<String, String> f2 = x -> x.toUpperCase();
     System.out.println(f2.apply("f2 hello"));

     // 写法三
     Function<String, String> f3 = String::toUpperCase;
     System.out.println(f3.apply("f3 hello"));
}

输出结果:
F1 HELLO
F2 HELLO
F3 HELLO

Predicate(断言型接口)

接收一个参数返回布尔值,其函数描述符为T -> boolean
@FunctionalInterface
public interface Predicate<T> {

    boolean test(T t);

    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

    default Predicate<T> negate() {
        return (t) -> !test(t);
    }

    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }

    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
        ? Objects::isNull
        : object -> targetRef.equals(object);
    }
}
public static void main(String[] args) {
    // 写法一
    Predicate<Integer> p1 = new Predicate<Integer>() {
        @Override
        public boolean test(Integer num) {
            return num % 2 == 0;
        }
    };

    System.out.println(p1.test(2));

    // 写法二
    Predicate<Integer> p2 = num -> num % 2 == 0;
    System.out.println(p2.test(2));
}

输出结果:
true
true

Consumer(消费型接口)

接收一个参数无返回值,其函数描述符为T -> void
@FunctionalInterface
public interface Consumer<T> {

    void accept(T t);

    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}
public static void main(String[] args) {
    // 写法一
    Consumer<String> c1 = new Consumer<String>() {
        @Override
        public void accept(String x) {
            System.out.println(x);
        }
    };
    c1.accept("c1 hello");

    // 写法二 Lambda
    Consumer<String> c2 = x -> System.out.println(x);
    c1.accept("c2 hello");

    // 写法三 方法引用
    Consumer<String> c3 = System.out::println;
    c1.accept("c3 hello");
}

输出结果:
c1 hello
c2 hello
c3 hello

Supplier(供给型接口)

无参数,只有返回值,其函数描述符为()-> T
@FunctionalInterface
public interface Supplier<T> {
    T get();
}
public static void main(String[] args) {
    // 写法一
    Supplier<Integer> s1 = new Supplier<Integer>() {
        @Override
        public Integer get() {
            return 10;
        }
    };

    System.out.println(s1.get());

    // 写法二
    Supplier<Integer> s2 = () -> 10;
    System.out.println(s2.get());
}

控制台输出结果如下:
10
10

为什么Java引入函数式接口?

函数式接口的引入主要是为了支持行为参数化,即允许将代码作为数据传递。
具体来说,函数式接口的引入有以下几个原因和优势:

  • 简化代码: 使用函数式接口可以大幅减少代码量,使代码更加简洁易读。Lambda表达式和方法引用提供了一种更简洁的方式来实现接口。
  • 提高灵活性: 函数式接口使得在设计API时可以更加灵活地接受不同的行为参数,这在设计可配置和可扩展的系统时非常有用。
  • 性能优化: 在某些情况下,使用函数式接口可以带来性能上的优化,因为它们通常会被编译器优化为更高效的形式。

综上所述,函数式接口的引入为Java开发者提供了一种新的编程范式,使得代码更加简洁、灵活和高效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丿微风乍起

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值