栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JDK8-函数式接口

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JDK8-函数式接口

函数式接口 函数式接口的由来

​ 我们知道使用Lambda表达式的前提是需要有函数式接口,而Lambda表达式使用时不关心接口名,抽象方法名。只关心抽象方法的参数列表和返回类型。

因此为了我们使用Lambda表达式更加的方法,在JDK中提供了大量常用的函数式接口。

public class Demo01Function {

    public static void main(String[] args) {

        fun1(arr -> {
            int sum = 0;
            for (int i : arr) {
                sum +=i;
            }
            return sum;
        });
    }

    public static void fun1(Operator operator){
        int[] arr ={1,2,3,4};
        int sum = operator.getSum(arr);
        System.out.println(sum);
    }
}


@FunctionalInterface
interface Operator{
    int getSum(int[] arr);
}

必须始终使用@Functionallnterface 注解对自己编写的函数式接口进行标注

函数式接口介绍
接口函数签名范例
Perdiicateboolean test(T t)Collection::isEmpty
FunctionR apply(T t)Arrays::asList
SupplierT get()Instant::now
ConsumerVoid accept(T t)System.out::println
UnaryOperatorT apply(T t)String::ToLowerCase
BinaryOperatorT apply(T t1,Tt2)BigInteger:add

​ 在JDK中帮我们提供了大量的函数式接口,主要是在java.util.function 包中。上面的这6个基础接口还有3种变体,分别可以作用基本类型 int、long 和 double。它们的命名方式是在基础接口饿前面加上基本类型而得。

​ Function 接口还有9种变体,用于结果类型为基本类型的情况。源类型和结果类型始终不一样,因为从类型到自身的函数就是 UnaryOperator。如果源类型和结果类型均为基本类型,就是在Function前面添加格式如SrcToResult,如 LongToIntFunction(有6种变体)。如果源类型为基本类型,结果类型是一个对象参数,则要在Function前面添加ToObj,如 DoubleToObjFunction(有三种变体)。

​ 这三种基础函数接口还有带两个参数的版本,如 BiPredocate、BiFunction和BiConsumer。还有BiFunction变体用于返回三个相关的基本类型:ToIntBiFunction、ToLongBiFunction和ToDoubleBiFunction。Consumer接口也有带两个参数的变体版本,它们带一个对象引用和一个基本类型:Obj-DoubleConsumer、ObjIntConsumer和ObjLongConsumer。

​ 最后,还有BooleanSupplier接口,它是Supplier接口的一种变体,返回boolean值。这是在所有的标准函数接口名称中唯一显示提到boolean类型的,但boolean返回值是通过Predicate及其4种变体来支持的。

1.supplier

无参有返回值的接口,需要提供一个返回类型

@FunctionalInterface
public interface Supplier {

    
    T get();
}

使用示例:

public class SupplierTest {

    public static void main(String[] args) {

        fun1(() -> {
            //计算出数组中最大的值
            int[] arr = {22, 55, 66, 33, 12, 43, 35};
            Arrays.sort(arr);
            return arr[arr.length-1];
        });
    }

    public static void fun1(Supplier supplier) {
        // get() 是一个无参的又返回值的 抽象方法
        Integer max = supplier.get();
        System.out.println("max = " + max);
    }
}
2.Consumer

有参无返回值的接口,使用的时候需要指定一个泛型来定义参数类型

@FunctionalInterface
public interface Consumer {

    
    void accept(T t);

    
    default Consumer andThen(Consumer after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}
2.1 accept方法

使用示例:将输入的数据统一转换为小写输出

public class ConsumerTest {

    public static void main(String[] args) {
        test(msg -> {
            System.out.println(msg + "->转换为小写:" + msg.toLowerCase());
        });
    }

    public static void test(Consumer consumer) {
        consumer.accept("Hello World");
    }
}
2.2 andThen默认方法

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

public class ConsumerTest {

    public static void main(String[] args) {
        testAndThen(msg1 -> {
            System.out.println(msg1 + "->转换为小写:" + msg1.toLowerCase());
        },msg2->{
            System.out.println(msg2 + "->转换为小写:" + msg2.toUpperCase());
        });
    }

    public static void testAndThen(Consumer con1,Consumer con2){
        String str = "Hello Wolrd";
        con1.andThen(con2).accept(str);  // 先转换为小写,在转换为大写
        System.out.println("------------------");
        con2.andThen(con1).accept(str);  // 先转换为大写,在转换为小写
    }
}
3.function
@FunctionalInterface
public interface Function {

    
    R apply(T t);

    
    default  Function compose(Function before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    
    default  Function andThen(Function after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

    
    static  Function identity() {
        return t -> t;
    }
}
3.1 apply方法

有参数又返回值的方法,Function接口是根据一个类型得到另一个类型的数据,前者称为前置条件,后者称为后置条件

public class FunctionTest {

    public static void main(String[] args) {
        fun1(msg -> {
            return Integer.parseInt(msg);
        });
    }

    
    public static void fun1(Function function) {
        Integer apply = function.apply("666");
        System.out.println("apply = " + apply);
    }
}
3.2 andThen默认方法
public class FunctionTest {

    public static void main(String[] args) {
        fun2(msg -> Integer.parseInt(msg),msg2-> msg2 * 10);
    }

    
    public static void fun2(Function fun1,Function fun2){
        Integer apply = fun1.andThen(fun2).apply("666");
        System.out.println("apply = " + apply);
    }
}
3.3 compose默认方法

compose方法正好更andThen方法执行顺序相反,

public class FunctionTest {

    public static void main(String[] args) {
        fun2(msg -> Integer.parseInt(msg),msg2-> msg2 * 10);
    }

    public static void fun2(Function fun1,Function fun2){
        Integer apply = fun2.andThen(fun1).apply("666");
        System.out.println("apply = " + apply);
    }
}
3.4 identity静态方法

identity静态方法是,输入什么类型的参数就返回什么类型

4.Predicate
@FunctionalInterface
public interface Predicate {

    
    boolean test(T t);

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

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

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

    
    static  Predicate isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}
4.1 test方法
public class PredicateTest {

    public static void main(String[] args) {
        test(msg -> msg.length() > 3,"HelloWorld");
    }

    private static void test(Predicate predicate,String msg){
        boolean b = predicate.test(msg);
        System.out.println("b = " + b);
    }
}
4.2 and、or、negate
public class PredicateTest {

    public static void main(String[] args) {
        test(msg1 -> msg1.contains("H"),msg2->msg2.contains("W"));
    }

    private static void test(Predicate p1,Predicate p2){
        // p1 包含H 同时 p2 包含 W
        boolean b1 = p1.and(p2).test("Hello");
        // p1 包含 H 或者 p2 包含 W
        boolean b2 = p1.or(p2).test("Hello");
        //p1 不包含H
        boolean b3 = p1.negate().test("Hello");

        System.out.println("b1 = " + b1);  //false
        System.out.println("b2 = " + b2); //true
        System.out.println("b3 = " + b3); //false
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/878184.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号