三、函数式接口

自定义函数式接口

  • Lambda表达式需要函数式接口的支持
  • 函数式接口定义:接口中只有一个抽象方法的接口,称为函数式接口。
  • 可以使用注解 @FuncitonalInterface 修饰,其修饰作用为:限定该接口必须为函数式接口,即该接口中有且只有一个抽象方法。否则无法通过编译。即可以检查是否为函数式接口。

实现

    /**
     * 自定义函数接口
     * @param <T>
     * @param <R>
     */
    @FunctionalInterface
    public interface Operation<T,R> {
        R operation(T t1, T t2);
    }
    /**
     * 具体实现方法
     * @param l1
     * @param l2
     * @param operation
     */
    public void op (Long l1, Long l2, Operation<Long,Long> operation){
        System.out.println(operation.operation(l1,l2));
    }

测试

   /**
     * 写具体实现方法再直接使用
     */
    @Test
    public void testOperation1(){
        GoodsService goodsService = new GoodsService();
        goodsService.op(10l,10l,(x,y) -> x*y);
        goodsService.op(100l,200l,(x,y)-> x+y);
    }

    /**
     * 先使用lambda表示具体实现方法体,再进行接口中的方法调用,传入具体值
     */
    @Test
    public void testOperation2(){
        Operation<Integer,Integer>  op = (x,y) -> x*y;
        System.out.println(op.operation(10,10));
    }

实际使用时,大多数情况下直接使用Java8内置四大函数式接口,并不要进行自己写函数式接口。

Java内置的四大核心函数式接口

  1. Consumer 消费型接口 消费对象
    • void accept(T t);
  2. Supplier 供给型接口 生成对象
    • T get();
  3. Function<R,T> 函数型接口 指定特定功能
    • R apply(T t);
  4. Predicate 断言型接口 进行条件判断
    • boolean test(T t);

案例

   /**
     * Consumer<T> 消费型接口
     * void accept(T t);
     *
     * @param n
     * @param con
     */
    public void consume(Integer n , Consumer<Integer> con){
        con.accept(n);
    }

    /**
     * Supplier<T> 供给型接口
     * T get();小括号无参数
     *
     * 调用此方法时,第二个参数提供一个数字集合
     * @param n
     * @param sup
     * @return
     */
    public List<Integer> getNumList(int n, Supplier<Integer> sup){
        List<Integer> numList = new ArrayList<>();

        for (int i = 0; i < n; i++){
            numList.add(sup.get()); //通过get方法得到数字 存到numList
        }
        return numList;
    }

    /**
     * Function<R,T> 函数型接口 指定特定功能
     * 定义一个处理字符串功能型接口函数
     * @param str
     * @param fun
     * @return
     */
    public  String strHandler(String str, Function<String,String> fun){
        return fun.apply(str);
    }

    /**
     * Predicate<T> 条件判断
     * boolean test(T t); 返回boolean
     * 使用断言型接口过滤字符串
     * @param strs
     * @param pred
     * @return
     */
    public List<String> strFilter(List<String> strs, Predicate<String> pred){
        List<String>  list = new ArrayList<>();
        for (String s:strs
        ) {
            //利用断言型接口进行指定功能判断  即一个功能性条件判断
            if(pred.test(s)){
                //过滤功能
                list.add(s);
            }
        }
        return list;
    }

测试

    @Test
    public void testConsumer(){
        FunctionInterface functionInterface = new FunctionInterface();
        //此时的(d) 小括号里有参数
        //原因是因为 Consumer接口有参数
        functionInterface.consume(1000,(d)-> System.out.println(d));
    }

    @Test
    public void testSupplier(){
        FunctionInterface functionInterface = new FunctionInterface();
        //T get(); 小括号无参数
        List<Integer> numList = functionInterface.getNumList(10,() -> (int)(Math.random()*101));
        for ( Integer i: numList
        ) {
            System.out.println(i);
        }
    }
    @Test
    public void testFunction(){
        FunctionInterface functionInterface = new FunctionInterface();
        //将字符串转成大写
        String str1 = functionInterface.strHandler("ghslkajh", (s) -> s.toUpperCase());
        System.out.println(str1);
    }
    @Test
    public void testPredicate(){
        FunctionInterface functionInterface = new FunctionInterface();
        //返回长度大于3的字符串
        List<String> s1 = functionInterface.strFilter(Arrays.asList("huzhiqi", "adaad", "1231", "414441", "gagsgasg"), (s) -> s.length() > 3);
        System.out.println(s1); //[huzhiqi, adaad, 1231, 414441, gagsgasg]
        //返回包含d的字符串
        List<String> s2 = functionInterface.strFilter(Arrays.asList("huzhiqi", "adaad", "1231", "414441", "gagsgasg"), (s) -> s.contains("d"));
        System.out.println(s2); // [adaad]
    }
原文地址:https://www.cnblogs.com/bigfairy/p/14002056.html