前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >函数式接口

函数式接口

原创
作者头像
HLee
修改2021-09-15 10:13:28
7000
修改2021-09-15 10:13:28
举报
文章被收录于专栏:房东的猫

简介

所谓的函数式接口,实际上就是接口里面只能有一个抽象方法的接口。Comparator接口就是一个典型的函数式接口,它只有一个抽象方法compare。

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

甚至可以说:函数式接口是专门为lambda表达式准备的,lambda表达式是只实现接口中唯一的抽象方法的匿名实现类。

JDK中的函数式接口举例:

代码语言:javascript
复制
java.lang.Runnable,
java.util.Comparator,
java.util.concurrent.Callable
java.util.function包下的接口,如Consumer、Predicate、Supplier等

函数式接口

  • 默认方法通过实例调用;静态方法通过接口名调用。
  • 默认方法可以被继承,实现类可以直接调用接口默认方法,也可以重写接口默认方法;静态方法不能被继承,实现类不能重写接口静态方法,只能使用接口名调用。
代码语言:javascript
复制
public interface Animal {

    /**
     * 接口中的抽象方法
     */
    void call();

    /**
     * 接口中的默认方法
     * @param food
     */
    default void like(String food) {
        System.out.println("我喜欢吃:" + food);
    }

    /**
     * 接口中的静态方法
     * @param food
     */
    static void hite(String food) {
        System.out.println("我不喜欢吃:" + food);
    }
}
代码语言:javascript
复制
public class Dog implements Animal{

    @Override
    public void call() {
        System.out.println("我是一只 little Dog");
    }
}
代码语言:javascript
复制
public class InterfaceTest {

    public static void main(String[] args) {

        Dog dog = new Dog();
        dog.call();
        dog.like("骨头");
        Animal.hite("稀饭");
    }
}

我是一只 little Dog
我喜欢吃:骨头
我不喜欢吃:稀饭

default方法

default关键字,在java8之前接口是不能有方法的实现,所有方法全都是抽象方法,实现接口就必须实现接口里面的所有方法。这就导致一个问题:当一个接口有很多的实现类的时候,修改这个接口就变成了一个非常麻烦的事,需要修改这个接口的所有实现类。

这个问题困扰了java工程师许久,不过在java8中这个问题得到了解决,没错就是default方法:

  • default方法可以有自己的默认实现,即有方法体;
  • 接口实现类可以不去实现default方法,并且可以使用default方法或者重写;

static方法

常用函数式接口

Supplier

描述:用来生产数据。

代码语言:javascript
复制
@FunctionalInterface
public interface Supplier<T> {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}

例:使用Supplier计算数组中最大的数

代码语言:javascript
复制
public class SupplierTest {

    public static void main(String[] args) {
        fun(() -> {
            int[] number = {1, 2, 3, 4, 5};
            Arrays.stream(number);
            return number[number.length - 1]; // 这个return就是 supplier.get();
        });

    }

    private static void fun(Supplier<Integer> supplier) {
        Integer max = supplier.get();
        System.out.println("Max: " + max);
    }
}

Consumer

描述:有参无返回值的接口,用来消费数据。使用的时候需要指定泛型来定义参数类型。

代码语言:javascript
复制
@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); };
    }
}

例如:将输入的数据统一转换为小写输出。

代码语言:javascript
复制
public class ConsumerTest {

    public static void main(String[] args) {
        fun((msg) -> {
            System.out.println(msg.toLowerCase());
        });
    }

    public static void fun(Consumer<String> consumer) {
        consumer.accept("Hello World");
    }
}

默认andThen方法,如果一个方法的参数和返回值都是Consumer,那么就可以实现效果,消费一个数据的时候首先做一个操作,然后做一个操作,实现组合。

代码语言:javascript
复制
public class ConsumerTest {

    public static void main(String[] args) {
    
        fun2((msg1) -> {
            System.out.println(msg1.toLowerCase());
        }, (msg2) -> {
            System.out.println(msg2.toUpperCase());
        });

    }

    public static void fun2(Consumer<String> c1, Consumer<String> c2) {
//        c1.accept("Hello World"); // 转小写
//        c2.accept("Hello World"); // 转大写

        c1.andThen(c2).accept("Hello World");
    }
}

Function

描述:有参数有返回值的接口。Function接口是根据一个类型的数据得到另一个类型的数据。前者为前置条件,后者为后置条件

代码语言:javascript
复制
@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;
    }
}

例如:传进去一个字符串,返回一个Integer类型。

代码语言:javascript
复制
public class FunctionTest {

    public static void main(String[] args) {
        fun((msg) -> {
            return Integer.parseInt(msg); // 方法体
        });
    }

    public static void fun(Function<String, Integer> function) {
        Integer integer = function.apply("727");
        System.out.println(integer);
    }
}

默认andThen方法,也是用来进行组合操作的。

代码语言:javascript
复制
public class FunctionTest {

    public static void main(String[] args) {

        fun2((msg1) -> {
            return Integer.parseInt(msg1);
        }, (msg2) -> {
            return msg2 * 10;
        });
    }

    public static void fun2(Function<String, Integer> f1, Function<Integer, Integer> f2) {
//        Integer s1 = f1.apply("22");
//        Integer s2 = f2.apply(s1);

        Integer s2 = f1.andThen(f2).apply("22");

        System.out.println(s2);
    }
}

Predicate

代码语言:javascript
复制
@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);

    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);
    }
}

例如:用于判断

代码语言:javascript
复制
public class PredicateTest {

    public static void main(String[] args) {
        fun(m -> {
            return m.length() > 2;
        }, "hello");
    }

    public static void fun(Predicate<String> predicate, String msg) {
        boolean is = predicate.test(msg);
        System.out.println(is);
    }
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 函数式接口
    • default方法
      • static方法
      • 常用函数式接口
        • Supplier
          • Consumer
            • Function
              • Predicate
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档