函数式接口详解

函数式接口

以前一直好奇java能不能传参的时候参数为方法,现在通过函数式接口可以做到了。以前一直用的不多,最近用到了就做一个简单的汇总以及演示demo。

1.什么是函数式接口?

  • 只包含一个抽象方法的接口,称为函数式接口
  • 你可以通过Lambda表达式来创建该接口的对象。(若Lambda表达式抛出一个受检异常,那么该异常需要在目标接口的抽象方法上进行声明)
  • 我们可以在任意函数式接口上使用@FunctionalInterface注解,这样做可以检查它是否是一个函数式接口,同时javadoc也会包含一条声明,说明这个接口是一个函数式接口

2.自定义函数

package function;

/**
 * @Description todo
 * @Author cz
 * @Date 2022/3/4
 */
public class Function {


    @FunctionalInterface
    public interface Func<T> {
        T get();
    }

    public static class FuncImpl implements Func<Integer> {

        @Override
        public Integer get() {
            return 3;
        }
    }

    public static Integer getInteger(Func<Integer> func) {
        return func.get();
    }

    public static void testFunc(){
        //匿名内部类的方式
        System.out.println(getInteger(new Func<Integer>() {

            @Override
            public Integer get() {
                return 3;
            }
        }));
        //Lambda形式
        System.out.println(getInteger(() -> 3));
        //实现类的方式
        System.out.println(getInteger(new FuncImpl()));
    }

    public static void main(String[] args) {
        //测试Function
        testFunc();
    }
}

3.JAVA内置四大核心函数式接口

在学习lambda表达式的时候,我们知道,要使用lambda表达式,我们就要创建一个函数式接口,那每次用lambda表达式的时候岂不是很麻烦,这时候,java给我们内置了四大核心函数式接口。

函数式接口 参数类型 返回类型 用途
Consumer 消费型接口 T 对类型为T的对象应用操作,包含方法:void accept(T t)
Supplier 共给型接口 T 返回类型为T的对象,包含方法:T get()
Function<T, R> 函数型接口 T R 对类型为T的对象应用操作,并返回结果,结果是R类型的对象,包含方法:R apply(T t)
Predicate 断定型接口 T boolean 确定类型为T的对象是否满足某约束,并返回boolean值。包含方法boolean test(T t)

还有一些其他接口可看参照里面的官方jdk文档里面,或是直接看 java.util.function 包下面的接口

4.四大接口示例

4.1 Consumer:消费型接口

image

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

void accept(T t)

 public static class ConsumerAcceptImpl implements Consumer<String> {

        @Override
        public void accept(String s) {
            System.out.println(s);
        }
    }

    public static void testConsumerAccept(String name, Consumer<String> consumer){
        //do something with name
        //then consumer the name
        String helloName = String.format("hello %s", name);
        consumer.accept(helloName);
    }

    public static void testAcceptMain(){
        //lambda表达式
        testConsumerAccept("张三", System.out::println);
        //Consumer的实现类
        testConsumerAccept("张三", new ConsumerAcceptImpl());
        //匿名内部类
        testConsumerAccept("张三", new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
    }

Consumer andThen(Consumer<? super T> after)

 public static void testConsumerAndThen() {
        Consumer<Student> c1 = (Student s) -> System.out.printf("%s:%s%n","c1", s.getSchool());
        Consumer<Person> c2 = (Person p) -> System.out.printf("%s:%s%n", "c2", p.getName());
        Consumer<Student> c3 = c1.andThen(c2);

        Student s = new Student("s1的school", new Person("p", 11));
        s.setName("student父类person的属性name");
        c3.accept(s);
    }

				/*  运行结果
        c1:s1的school
        c2:student父类person的属性name

        返回一个 consumer 的accept 为 先执行c1的accept然后执行c2的accept
        */

4.2 Supplier:共给型接口

image

@FunctionalInterface
public interface Supplier<T> {

    T get();
}

T get( )

		//需求:产生指定个数的整数,并放入集合中
    public static List<Integer> getNumList(int num, Supplier<Integer> sup){
        List<Integer> list = new ArrayList<>();
        for(int i=0;i<num;i++) {

            Integer n = sup.get();
            list.add(n);

        }
        return list;
    }

    public static void testSupplierGet() {
        List<Integer> numList = getNumList(10, ()->(int)(Math.random()*100 ));
        for (Integer integer : numList) {
            System.out.println(integer);
        }
    }

4.3 Function<T,R>:函数型接口

image
image

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

R apply(T t)

		//需求:用于处理字符串
    public  static String strHandler(String str, Function<String,String> fun) {
        System.out.println("这里先处理,然后交给fun处理,这里的处理算是strHandler处理的。");
        return fun.apply(str);
    }

    /*
    对类型为T的对象应用操作返回类型为R的对象
     */
    public static void  testFunctionApply() {
        String trimStr=strHandler("\t\t你好,world     ",(str) -> {
            System.out.println("这里算是fun处理的,需要返回值");
            return str.trim();
        });
        System.out.println(trimStr);
    }

Function<T,V> compose(Function<? super V, ? extends T> before)

  public static void testFunctionCompose(){
        Function<String, String> before = String::trim; //对入参的String进行trim操作,返回trim以后的String;
        Function<String, String> f2 = str -> str.replace("hello", "你好"); //对入参的String里面的hello替换为你好
        String rt = f2.compose(before).apply("hello, world    ");
        System.out.println(rt);
        /* 此处compose的作用其实就是将多个Function的apply方法连接在一起用,compose里面的将Function的apply方法将提前于它的调用的那个
        Function的apply方法。看成是过滤器会很好理解。
        上述执行过程是 compose返回的Function f3.apply(f2.apply(before.apply(str)))
         */
    }

Function<T, V> andThen(Function<? super R, ? extends V> after)

 public static void testFunctionAndThen(){
        Function<String, String> after = String::trim; //对入参的String进行trim操作,返回trim以后的String;
        Function<String, String> f2 = str -> str.replace("hello", "你好"); //对入参的String里面的hello替换为你好
        String rt = f2.andThen(after).apply("hello, world    ");
        System.out.println(rt);
        /* 此处compose的作用其实就是将多个Function的apply方法连接在一起用,andThen里面的将Function的apply方法将后于它的调用的那个
        Function的apply方法。看成是过滤器会很好理解。
        上述执行过程是 andThen返回的Function f3.apply(after.apply(f2.apply(str)))
         */
    }

Function<T, T> identity()

 		/* 测试 Function<T, T> identity() 用法 
 		identity()返回的是一个入参和出参相同的Function*/
    public static void printString(String str, Function<String, String> f1){
        System.out.println(f1.apply(str));
    }

    public static void testFunctionIdentity(){
        printString("s1", Function.identity());
    }

4.4 Predicate:断言型接口

image

image

image

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

    @SuppressWarnings("unchecked")
    static <T> Predicate<T> not(Predicate<? super T> target) {
        Objects.requireNonNull(target);
        return (Predicate<T>)target.negate();
    }
}

boolean test(T t) 用来处理参数T,看是否满足要求,可以理解为 条件A

  public static void testPredicateTest(){
        Predicate<Integer> predicateTest = x -> x > 0;
        System.out.println(predicateTest.test(10));
    }
//true

Predicate and(Predicate<? super T> other) 返回一个Predicate, 同时满足this.test(T t)和other.test(T t)

public static void testPredicateAnd(){
        Predicate<Integer> predicate = x -> x > 0;
        Predicate<Integer> other = x -> x < 10;
        System.out.println(predicate.and(other).test(11));
    }
//flase

Predicate negate() 返回一个Predicate,且与之前 this.test()取反

 public static void testPredicateNegate(){
        Predicate<Integer> predicate = x -> x > 0;
        System.out.println(predicate.negate().test(10));
    }
 //false

Predicate or(Predicate<? super T> other) this.test()||other.test()

 public static void testPredicateOr(){
        Predicate<Integer> predicate = x -> x > 0;
        Predicate<Integer> other = x -> x < 0;
        predicate.or(other).test(0);
    }
    //false

Predicate isEqual(Object targetRef) 判断引用是否相等

 public static void testPredicateIsEqual(){
        Object obj = new Object();
        Predicate.isEqual(obj).test(obj);
    }
//true

Predicate not(Predicate<? super T> target) target.test()取反

public static void testPredicateNot(){
        Predicate<Integer> p1 = x -> x>0;
        System.out.println(Predicate.not(p1).test(-1));
    }
//true

5. 其他与Predicate相关的接口

  • BiPredicate<T, U>

    针对两个参数,看两个参数是否符合某个条件表达式

  • DoublePredicate

    看一个double类型的值是否符合某个条件表达式

  • IntPredicate

    看一个int类型的值是否符合某个条件表达式

  • LongPredicate

    看一个long类型的值是否符合某个条件表达式

参考:
1.https://www.jianshu.com/p/8005f32caf3d
2.https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/function/package-summary.html
3.https://www.jianshu.com/p/b38ff80e3039
4.源码地址:https://gitee.com/ashscc/java-ptn/tree/master/baseJDK/src/main/java/function
posted @ 2022-03-06 17:19  orangeScc  阅读(2783)  评论(0编辑  收藏  举报