【Java从头开始到光头结束】No12.JDK1.8 函数式编程之函数式接口

1.概述

  • 概念:
    有且仅有一个抽象方法的接口
  • 如何检测一个接口是不是函数式接口
    @FunctionalInterface 接口
    放在接口定义的上方:如果接口是函数式接口,编译通过;如果不是,编译失败
  • 总结:
    适用于lambda,专注做一件事情的接口。

2.常用接口↓↓↓

在函数式接口和Lambda表达式出现后,Java官方为我们提供了一些简单的函数式接口来完成一些操作(支持Stream流操作),Stream流的操作中我们会使用这些接口,因此学习如何使用这些接口是我们后续学习Stream流的前提条件,稍后我们在Stream流的学习中也会提到。

3.Supplier 接口

  • 描述

Supplier:供应商
我将其称之为提供者接口,其功能方法是 T get​()
在接口实现中对实例进行构建并返回。
在这里插入图片描述

  • 代码:T get​()
public class Supplier_Practice {
    
    

    public static void main(String[] args) {
    
    
        String str = getString(() -> {
    
    
           return "supplier interface";
        });
        System.out.println(str);
    }

    private static String getString(Supplier<String> stringSupplier) {
    
    
        return stringSupplier.get();
    }

}

4.Consumer 接口

  • 描述

Consumer :消费者
我将其称之为使用者接口,其功能方法是 void accept​(object)
传入一个参数,对其进行操作,无返回值。
在这里插入图片描述

  • 代码:void accept​(object)
public class Consumer_Practice {
    
    

    public static void main(String[] args) {
    
    

        String str = "chenfeilin";
        consumerString((String s) -> {
    
    
            System.out.println(s.toUpperCase());
        }, str);

    }

    private static void consumerString(Consumer<String> stringConsumer, String str) {
    
    
        stringConsumer.accept(str);
    }

}

  • 代码:andThen​(Consumer<? super T> after)
    返回一个组成的 Consumer ,依次执行此操作,然后执行 after操作。
// 一个简单的实体类
public class Student {
    
    

    private String name;
    private int age;
    private String address;

    public Student() {
    
    
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public int getAge() {
    
    
        return age;
    }

    public void setAge(int age) {
    
    
        this.age = age;
    }

    public String getAddress() {
    
    
        return address;
    }

    public void setAddress(String address) {
    
    
        this.address = address;
    }

    @Override
    public String toString() {
    
    
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }
}

public class Consumer_Practice {
    
    

    public static void main(String[] args) {
    
    

        Student student = new Student();
        consumerTwo((Student s1) -> {
    
    
            s1.setName("chenfeilin");
        }, (Student s2) -> {
    
    
            s2.setAddress("雷克雅未克");
            s2.setAge(777);
        }, student);
        System.out.println(student);

    }

    private static void consumerTwo(Consumer<Student> stringConsumer1,
                                    Consumer<Student> stringConsumer2, Student student) {
    
    
        // 依次消费
        stringConsumer1.andThen(stringConsumer2).accept(student);
    }

}

控制台输出:

Student{name=‘chenfeilin’, age=777, address=‘雷克雅未克’}

  • 注意
    对于String 类型,这个消费者的结果不会反应到原引用的值上,我们看实例代码
public class Consumer_Practice {
    
    

    public static void main(String[] args) {
    
    

        String str = "chenfeilin";
        consumerString((String s) -> {
    
    
            s = s.toUpperCase();
            System.out.println(s);
        }, str);
        System.out.println(str);
    }

    private static void consumerString(Consumer<String> stringConsumer, String str) {
    
    
        stringConsumer.accept(str);
    }
}

控制台输出结果:

CHENFEILIN
chenfeilin

String str 对象的值并没有改变。

5.Predicate 接口

  • 描述

Predicate :断言
我将其称之为判断者接口,其功能方法是 **boolean test(Object) **。
传入一个参数值,返回一个判断结果。
在这里插入图片描述


  • 代码:boolean test(Object)
public class Predicate_Practice {
    
    

    public static void main(String[] args) {
    
    

        String str = "chenfeilin";
        checkString((String s) -> {
    
    
            return s.length() > 3;
        }, str);

    }

    private static void checkString(Predicate<String> stringPredicate, String str) {
    
    
        boolean test = stringPredicate.test(str);
        if (test) {
    
    
            System.out.println("OK");
        } else {
    
    
            System.out.println("NG");
        }
    }

}

输出结果为:OK

  • 补充:作为一个断言,其判断条件应该是有组合形式的,例如 && || 等在这里插入图片描述

  • 代码

public class Predicate_Practice {
    
    

    public static void main(String[] args) {
    
    

        String str = "chenfeilin";
        moreCheck((String s1) -> {
    
    
            return s1.length() > 5;
        }, (String s2) -> {
    
    
            return s2.startsWith("ccc");
        }, str);

    }

    private static void moreCheck(Predicate<String> stringPredicate1,
                                  Predicate<String> stringPredicate2, String str) {
    
    

        boolean test1 = stringPredicate1.and(stringPredicate2).test(str);
        boolean test2 = stringPredicate1.or(stringPredicate2).test(str);
        boolean test3 = stringPredicate1.negate().test(str);

        System.out.println(test1);
        System.out.println(test2);
        System.out.println(test3);
    }

}

输出结果:
false
true
false

6.Function 接口

  • 描述

Function:功能
我将其称之为加工者接口,其功能方法是 **apply(Object) **。
传入一个参数(T类型),返回一个值(R类型)。
在这里插入图片描述

  • 代码:apply(Object)
public class Function_Practice {
    
    

    public static void main(String[] args) {
    
    

        int count = 33;
        function((Integer a) -> {
    
    
            return String.valueOf(a + 100);
        }, count);

    }

    private static void function(Function<Integer, String> integerStringFunction, int a) {
    
    
        String result = integerStringFunction.apply(a);
        System.out.println(result);
    }

}

输出结果为:133
  • 代码补充:andThen​(Function<? super R,? extends V> after)
    例如一个Function1的输入类型为A,输出类型为B,另一个Function2的入力参数类型刚好为B,则其可以形成一个链路,将Function1的返回值作为Function2的入力值,进行多次“加工”
public class Function_Practice {
    
    

    public static void main(String[] args) {
    
    

        int count = 33;
        moreFunction((Integer a) -> {
    
    
            return String.valueOf(a + 100);
        }, (String str) -> {
    
    
            return str.length() > 2;
        }, count);

    }

    private static void moreFunction(Function<Integer, String> function1,
                                     Function<String, Boolean> function2, int a) {
    
    
        Boolean aBoolean = function1.andThen(function2).apply(a);
        System.out.println(aBoolean);
    }

}

猜你喜欢

转载自blog.csdn.net/cjl836735455/article/details/108696996