简述函数式接口

本人小白一枚,欢迎大家一起讨论学习,如有错误,还望大家指教。

简述:

函数式接口,即适用于函数式编程场景的接口,而Java中的函数式编程体现就是Lambda,所以函数式接口就是可以适用于Lambda使用的接口。只有确保接口中有且仅有一个抽象方法,才可以让Java中的Lambda语法顺利的进行推导。

格式:

定义一个接口且该接口仅有一个抽象方法,在Java8中专门为函数式接口引入了一个新的注解:@FunctionalInterface。该注解可用于定义函数式接口,并且被该注解修饰后,编译器将会强制检查该接口是否仅有一个抽象方法,否则将会报错。注意:可以不使用该注解定义函数式接口,只要符合函数式接口的定义,该接口也是一个函数式接口,使用该注解可以增强代码的阅读性和规范性。

// 也可以使用@FunctionalInterface注解
public interface 接口名 {
    public abstract 返回值类型 方法名称(可选参数信息);
}

常用函数式接口

JDK提供了大量常用的函数式接口以丰富Lambda的典型使用场景,他们主要在java.util.function包中。下面我们简单了解几个。
一、Supplier接口(供给型接口)
该接口提供一个无参方法:T get()。用来获取一个泛型参数指定的对象数据。由于这是一个函数式接口,这也就意味对应的Lambda表达式需要对外提供一个符合泛型类型的对象数据。
例子:使用该接口求数组元素的最大值,该接口作为方法参数类型

public static void main(String[] args) {
    Integer[] arr = new Integer[] {5, 48, 12, 99, 2, 7};
    int max = getMax(() -> {
        int num = arr[0];
        for(int item : arr) {
            if (num < item) {
                num = item;
            }
        }
        return num;
    });
    System.out.println("最大值为:" + max);
}
public static Integer getMax(Supplier<Integer> supplier) {
    return supplier.get();
}

最大值为:99

二、Consumer接口(消费性接口)
java.util.function.Consumer<T>接口则正好与Supplier接口相反,它不是生产一个数据,而是消费一个数据,其数据类型有泛型来决定。该接口提供一个抽象有参方法: void accept(T t) ,意为消费一个指定泛型的数据。还提供一个默认方法:Consumer<T> andThen(Consumer<? super T> var),下面是JDK的源代码:

// java.util.Objects 的 requireNonNull 静态方法将会在参数为null时主动抛出,
// NullPointerException 异常。这省去了重复编写if语句和抛出空指针异常的麻烦。 
default Consumer<T> andThen(Consumer<? super T> after) {   
  Objects.requireNonNull(after);     
  return (T t)> { accept(t); after.accept(t); }; 
}

例子:将字符串数组按照:“姓名:xx,性别:xx”的格式将信息打印出来。

public static void main(String[] args) {
   String[] array = {"迪丽热巴,女", "古力娜扎,女", "马尔扎哈,男"};
   myAndThen((s) -> System.out.print("姓名:" + s.split(",")[0]),
             (s) -> System.out.println(",年龄:" + s.split(",")[1]),
             array);
}

public static void myAndThen(Consumer<String> one, Consumer<String> two, String[] array) {
    for (String str : array) {
        one.andThen(two).accept(str);
    }
}

姓名:迪丽热巴,年龄:女
姓名:古力娜扎,年龄:女
姓名:马尔扎哈,年龄:男

三、Predicate接口(断言型接口)
当我们需要对某种类型的数据进行判断,从而得到一个boolean值结果时,这时就可以使用java.util.function.Predicate<T>接口。该接口提供了一个抽象方法:boolean test(T t),用于条件判断的场景。
该接口还提供一个默认方法:default Predicate<T> and(Predicate<? super T> other),此方法将两个predicate条件使用与逻辑连接起来使用并且的效果,下面为JDK源码:

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

例子:判断一个字符串既要包含大写“H”又要包含大写“W”。

public static void main(String[] args) {
     boolean flag = checkString("aHdfWh", str -> str.contains("H"), str -> str.contains("W"));
     System.out.println(flag);
 }
 public static boolean checkString(String str, Predicate<String> one, Predicate<String> two) {
     return one.and(two).test(str);
 }

默认方法or:default Predicate<T> or( Predicate<? super T> other),该方法与and方法类似,实现逻辑关系中的“”,其下为源码:

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

默认方法非:default Predicate<T> negate( ),该方法实现逻非(取反),以下为该方法的源代码:

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

例子:判断字符串的长度是否小于小等于5。

private static boolean method(String str, Predicate<String> predicate) {
    return predicate.negate().test(str);
}

public static void main(String[] args) {
    boolean flag = method("abcd56", (str) -> str.length() > 5);
    System.out.println(flag);
}

四、Function接口(功能型接口)
java.util.function.Function<T,R>接口用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后者称为后置条件。
抽象方法apply:R apply(T t) 该接口最主要的抽象方法,根据类型T的参数获取类型R的结果。
默认方法andThen:用来进行组合操作,源码如下:

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

例子:将字符串截取数字年龄部分,得到字符串,将得到的字符串转换为int类型的数字,将数字加上100并返回

public static void main(String[] args) {
        System.out.println(method("赵丽颖,20",
                str -> str.split(",")[1],
                str -> Integer.parseInt(str),
                num -> num += 100));
    }

    public static Integer method(String str, Function<String, String> one, Function<String, Integer> two, Function<Integer, Integer> three) {
        return one.andThen(two).andThen(three).apply(str);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值