Java8新特性--函数式接口

一. 函数式接口

  • 概念

    函数式接口在java中指的是:有且只有一个抽象方法的接口

  • @FunctionalInterface注解

    java8中专门为函数式接口引入一个新的注解,叫**@FunctionalInterface**,该注解用在接口的定义上

    比如:

    @FunctionalInterface
    public interface Animal {
        public abstract void eat();
        // public abstract void walk();
    }
    

    注意:一旦使用了这个FunctionalInterface注解定义接口,编译器就会检查接口是否有且只有一个抽象方法,没有满足的话就会报错。(但是即使没有使用这个注解,只要接口满足函数接口的要求,仍是一个函数接口,加这个注解只是帮助检查)

    FunctionalInterface.png

  • 关于接口中的static方法和default方法

    • static方法

      java8中接口可以定义一个或多个static方法,使用方法和普通static方法一样。

      注意:实现接口的类或者子接口是不会继承接口中的静态方法的

    • default方法

      java8在接口中新增的default定义方法,default默认方法不是抽象方法,不会影响函数接口的判断。

      定义的default方法,子接口或实现类可以不需要实现,直接调用,也可以重写这个default定义的方法(重写时候不需要加default关键字)。

    注意:函数式接口中有且只能有一个抽象方法,但可以有多个static方法或default方法。

二. 常用函数式接口

常用的函数式接口主要在包java.util.function中提供,主要有以下几种常用接口。

  1. Supplier<T>–供给型接口

    • 抽象方法

      T get():返回指定泛型的数据

      由于Supplier是一个函数式接口,意味着使用Lambda表达式时需要供给一个符合泛型类型的对象数据。

    import java.util.function.Supplier;
    
    public class FunctionInterfaceDemo {
        public static void main(String[] args) {
            String str1 = "Hello";
            String str2 = "Java";
    
            String s = strConcat(()-> str1 + str2);
            System.out.println(s);
        }
        
        // 拼接字符串
        public static String strConcat(Supplier<String> supplier) {
            return supplier.get();
        }
    }
    

    其实就是使用函数式接口作为函数参数,调用时使用Lambda表达式实现函数式接口的抽象方法。

    而Supplier的抽象方法get是返回一个泛型类型的数据对象,这里是String,所以返回一个String。

  2. Consumer<T>–消费型接口

    • 抽象方法

      void accept(T t):对给定的参数执行此操作(消费数据t)

    • 默认方法

      default Consumer<T> andThen(Consumer<? supper T> after):组合消费,先执行调用andThen接口的对象的accept方法,再执行after中的accept方法。

    accept()使用实例:

    import java.util.function.Consumer;;
    
    public class FunctionInterfaceDemo {
        public static void main(String[] args) {
            String str = "Hello World";
            consumeStr(str, (s) -> System.out.print(s));
        }
        // 消费字符串
        public static void consumeStr(String str, Consumer<String> consumer) {
            consumer.accept(str);
        } 
    }
    

    andThen()使用实例:

    import java.util.function.Consumer;;
    
    public class FunctionInterfaceDemo {
        public static void main(String[] args) {
            String str = "Hello World";
            consumeStr(str, 
                    (s) -> System.out.println(s.toUpperCase()),
                    (s) -> System.out.println(s.toLowerCase()));
        }
        // 消费字符串,先变大写,再变小写
        public static void consumeStr(String str, Consumer<String> con1, Consumer<String> con2) {
            con1.andThen(con2).accept(str);
        } 
    }
    
  3. Predicate<T>–断言型接口

    • 抽象方法

      boolean Test(T t):传入一个参数,返回一个布尔值

    • 默认方法

      • default Predicate<T> and(Predicate<? super T> other):相当于逻辑运算中的与&&,当两个Predicate函数返回结果都是true时才返回true。
      • default Predicate<T> or(Predicate<? super T> other):相当于逻辑运算中的或||,当两个Predicate函数返回结果有一个为true,则返回true,否则返回false。
      • default Predicate<T> negate():相当于逻辑运算中的!,就是取反的意思。

    test()实例:

    import java.util.function.Predicate;;;
    
    public class FunctionInterfaceDemo {
        public static void main(String[] args) {
           Predicate<Integer> predicate1 = (t) -> t > 0;
           // 执行test方法,会将参数10 进行 t>0 判断,结果返回true
           System.out.println(predicate1.test(10));
        }
    }
    

    and(),or(),negate()实例:

    import java.util.function.Predicate;;;
    
    public class FunctionInterfaceDemo {
        public static void main(String[] args) {
            /**
             * 两个条件同时成立:
             * 1. 字符串长度大于5
             * 2. 以'A'开头
             */
            String[] array = {"Hello", "Air", "Apple", "Another"};
            Predicate<String> pre1 = (t) -> t.length() > 5;
            Predicate<String> pre2 = (t) -> t.startsWith("A");
            for (String s : array) {
                if(pre1.and(pre2).test(s) == true) {
                    System.out.println(s);
                }
            } // 输出Another
            System.out.println("---------------");
            /**
             * 只要有一个条件成立:
             * 1. 字符串长度大于5
             * 2. 以'A'开头
             */
            for (String s : array) {
                if(pre1.or(pre2).test(s) == true) {
                    System.out.println(s);
                }
            } // 输出Air,Apple,Another
            System.out.println("---------------");
            /**
             * 取反:
             * 1. 字符串长度大于5
             */
            for (String s : array) {
                if(pre1.negate().test(s) == true) {
                    System.out.println(s);
                }
            } // 输出Hello,Air,Apple
        }
     
    }
    
  4. Function<T,R>–函数型接口

    该接口用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后者称为后置条件。

    • 抽象方法

      R accept(T t):根据类型T的参数获取参数类型R的结果。

    • 默认方法

      • default <V> Function<T, V> andThen(Function<? super R, ? extends V> after):组合操作,先执行调用andThen函数的对象的apply方法,然后再执行参数after中的apply方法。
      • default <V> Function<V, R> compose(Function<? super V, ? extends T> before):与andThen相反,先调用before中的apply方法,再调用执行compose方法的对象中的apply方法。
    import java.util.function.Function;
    
    public class FunctionInterfaceDemo {
        public static void main(String[] args) {
            Function<Integer, Integer> func = (t) -> t * 2;
            System.out.println(func.apply(8));  // 输出 16
            System.out.println("------------");
    
            Function<Integer,Integer> fun1 = (t) -> t * t;
            Function<Integer,Integer> fun2 = (t) -> t + 2;
            // andThen和compose是相反的操作,相同的参数,结果完全不一样
            System.out.println(fun1.andThen(fun2).apply(8));    // 输出 66
            System.out.println(fun1.compose(fun2).apply(8));    // 输出 100
        }
    
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值