专栏首页后端JavaEE函数式接口小结

函数式接口小结

1. 概述

如果说一个接口内有且只有一个方法,而且该方法是一个缺省属性为public abstract方法,该接口可以称之为是一个函数式接口。

1.1@FunctionalInterface 使用

定义FunctionalInterface 接口

/**
 * 使用@FunctionalInterface检查函数式接口格式问题
 * 要求当前接口中有且只有一个缺省属性为public abstract的方法
 *
 * @author Anonymous 2020/3/11 9:55
 */
@FunctionalInterface
public interface FunctionalType {
    void test();
}

自定义Demo1类

/**
 * 自定义函数式接口作为方法的参数演示
 *
 * @author Anonymous 2020/3/11 9:55
 */
public class Demo1 {
    public static void main(String[] args) {
        /*
        使用匿名内部类来完成函数式接口的使用,但是这种方式有悖于函数式接口的目的
        Low

        useFunctionalInterface(new FunctionalType() {
            @Override
            public void test() {
                System.out.println("匿名内部类的匿名对象直接作为方法的参数。");
            }
        });
        int(*) (char **, int *)
            C语言中的函数指针
            如果是C语言中,这需要的参数是方法名
        */
       useFunctionalInterface(() -> System.out.println("函数式接口 lambda表达式实现完成方法,实现目的"));
    }

    /**
     * 使用一个函数式接口作为方法的参数
     *
     * @param ft 函数式接口的实现类对象,或者说直接操作本质,直接传入Lambda表达式
     */
    public static void useFunctionalInterface(FunctionalType ft) {
        ft.test();
    }
}

2.Java中提供的常用函数式接口

Supplier<T> 生产者, 返回一个指定类型的数据
Consumer<T> 消费者, 消耗一个指定类型的数据
Predicate<T> 判断调节,过滤使用
Function<T,R> 类型转换,根据你指定的类型T, 转换成对应类型R

2.1Supplier 生产者,返回一个指定的数据类型

有且只有一个方法 T get(); 不需要参数,返回指定T类型数据

/**
 * Supplier函数式接口演示
 *
 * @author Anonymous 2020/3/11 14:44
 */
public class Demo1 {
    public static void main(String[] args) {
        String msg1 = "异常位置XXX,";
        String msg2 = "异常问题XXX,";
        String msg3 = "异常时间XXX";

        /*
        这里需要的是一个函数式接口,直接传入一个lambda表达式
         */
        log(Level.HIGH, () -> {
            System.out.println("Lambda表达式执行!!!");
            return msg1 + msg2 + msg3;
        });

        /*
        Lambda表达式优化
         */
        log(Level.HIGH, () -> msg1 + msg2 + msg3);
    }

    /**
     * 根据日志等级Level来确定是否需要记录日志
     *
     * @param level Level枚举类型,有三个数据 HIGH MIDDLE LOWER
     * @param supplier Supplier函数式接口,利用T get() 完成提供数据操作
     */
    public static void log(Level level, Supplier<String> supplier) {
        /*
        Supplier函数式接口利用get方法,提供对应的返回指定String类型数据的操作
         */
        if (Level.HIGH == level) {
            // 通过函数式接口获取调用对应的returnLogMessage()方法
            System.err.println(supplier.get());
        }
    }
}

2.2Consumer消费者,处理数据

操作使用的方式是 void accept(T t); 根据接口指定的数据类型接收对应数据,进行处理和消费,对外没有任何的返回

/**
 * 使用Consumer处理数据
 *
 * @author Anonymous 2020/3/11 15:24
 */
public class Demo1 {
    public static void main(String[] args) {
        // 该方法需要的参数是一个String类型,同时使用Consumer接口处理数据
        // 因为Consumer接口是一个函数式接口,可以使用Lambda表达式
        testConsumer("宫保鸡丁,番茄牛腩,酱牛肉,黄焖鸡米饭", (str) -> {
            String[] split = str.split(",");

            for (String s : split) {
                System.out.println(s);
            }

        });
    }

    /**
     * 给予当前方法一个String类型,通过Consumer函数式接口中的accept方法完成对应
     * 字符串处理
     *
     * @param str String类型字符串
     * @param consumer Consumer处理数据的函数式接口
     */
    public static void testConsumer(String str, Consumer<String> consumer) {
        consumer.accept(str);
    }
}

2.3 Predicate 判断数据是否合适,返回true/false,基本使用+与或非(and+or+negate)

Predicate一般用于调节判断,过滤数据的方法 函数式接口中指定的方法 boolean test(T t); 处理T类型数据,返回boolean true / false

①基本使用

/**
 * 演示Predicate<T>基本使用
 *      boolean test(T t)
 *
 * @author Anonymous 2020/3/11 16:11
 */
public class Demo1 {
    public static void main(String[] args) {

        // Predicate函数式接口,使用Lambda表达式作为方法的参数
        boolean b = testPredicate("郑州奥力给!!!中国奥力给!!!",
                (str) -> {
                    return str.contains("加油");
                });

        System.out.println("ret : " + b);

        System.out.println("---------------------------");

        /*
        优化Lambda表达式,
            因为是一个参数,小括号可以省略
            就一行代码,大括号可以省略
            return也可以省略
         */
        testPredicate("郑州奥力给!!!中国奥力给!!!", str -> str.contains("加油"));
    }

    /**
     * 使用Predicate函数式接口利用boolean test(T t)对于当前数据进行判断操作,
     * 返回boolean类型数据
     *
     * @param str 需要进行判断数据的String类型字符串
     * @param pre 处理使用Predicate函数式接口
     * @return 判断接口是否满足要求,满足返回true,不满足返回false
     */
    public static boolean testPredicate(String str, Predicate<String> pre) {
        return pre.test(str);
    }
}

②与 :and

/**
* Predicate and使用
* default修饰方法add(Predicate<T> pre)
*      and就是逻辑运算符里面的 &&
*      同真为真,有假【即】假
*      需要对两个Predicate进行判断处理
*
*      例如:
*          pre1.test(str) && pre2.test(srt);
*          ==> pre1.and(pre2).test(str);
*
* @author Anonymous 2020/3/11 16:19
*/
public class Demo2 {
   public static void main(String[] args) {

       /*
       这里需要量Predicate接口,使用Lambda
        */
       boolean ret = testAnd("赶紧复工吧,不要搞事情了!!!",
               str -> str.length() > 5,
               str -> str.startsWith("赶紧"));

       System.out.println(ret);
   }

   /**
    * 组合判断
    *
    * @param str  需要判断的字符串
    * @param pre1 判断方式1
    * @param pre2 判断方式2
    * @return 处理结果 true, false
    */
   public static boolean testAnd(String str, Predicate<String> pre1, Predicate<String> pre2) {
       // return pre1.test(str) && pre2.test(str)
       return pre1.and(pre2).test(str);
   }
}

③或 : or

/**
 * Predicate or演示
 *
 * @author Anonymous 2020/3/11 16:32
 */
public class Demo3 {
    public static void main(String[] args) {
        boolean ret = testOr("国家之强大,国外人羡慕不得~~",
                str -> str.length() < 10,
                str -> str.contains("国家"));

        System.out.println(ret);
    }

    /**
     * or 组合判断
     *
     * @param str  需要判断的字符串
     * @param pre1 判断方式1
     * @param pre2 判断方式2
     * @return 处理结果 true, false
     */
    public static boolean testOr(String str, Predicate<String> pre1, Predicate<String> pre2) {
        // return pre1.test(str) || pre2.test(str);
        return pre1.or(pre2).test(str);
    }
}

④非 :negate

/**
* Predicate negate()操作
*
* @author Anonymous 2020/3/11 16:36
*/
public class Demo4 {
   public static void main(String[] args) {
       boolean ret = testNegate("疫情总会过去的!!!",
               str -> str.length() < 5);
       System.out.println(ret);
   }

   /**
    * negate操作
    *
    * @param str 字符串
    * @param pre Predicate函数式接口
    * @return 处理结果
    */
   public static boolean testNegate(String str, Predicate<String> pre) {
       // return !pre.test(str);
       return pre.negate().test(str);
   }
}

2.4Function<T,R> 类型转换

使用R apply(T t) 转换指定类型T到R

/**
 * Function<T, R>
 *     default修饰andThen方法使用
 *
 * @author Anonymous 2020/3/11 17:01
 */
public class Demo2 {
    public static void main(String[] args) {
        String s = testAndThen(10,
                i -> i + "",
                i -> i + "测试");

        System.out.println(s);
    }

    /**
     * 两次转换过程
     *
     * @param i 需要处理的类型
     * @param fun1 Function函数接口
     * @param fun2 Function函数接口
     * @return String类型
     */
    public static String testAndThen(int i, Function<Integer, String> fun1, Function<String, String> fun2) {

        // andThen使用,最后apply方法参数类型是fun1要求的转换参数类型
        return fun1.andThen(fun2).apply(i);
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • jdk1.8 自带的Base64加密与解密

  • JavaWeb使用德鲁伊(略)实现登录、激活码注册(发送激活码到邮箱,点击激活链接后,才能正常登陆)、注册界面

    1.注册–>2.注册页面–>3.(注册完点击提交到)激活界面–>点击激活链接可以到邮箱界面,从接收到的邮件里面点击立即激活 / 或者自己打开邮箱,从接收到的...

  • getParameterMap()返回参数需要对应实体类类型,否则收不到----打卡

  • Android 拓展Logger细节分享

    首先感谢orhanobut/logger库的作者提供了这么好用的日志管理工具。Github传送门 本文以orhanobut/logger为基础,通过阅读源码后...

    饮水思源为名
  • Java知识点——函数式接口

    用户7073689
  • 给定一个字符串数组,按照字典顺序进行从小到大的排序

     假设字符串数组是str[] = {"ab","cd","ef"},很明显答案就是”abcdef“最小,其实这是一道贪心问题,我的想法是将字符串数组进行内的字符...

    mathor
  • StringUtils的源码解析

    爱撒谎的男孩
  • 夯实Java基础系列3:一文搞懂String常见面试题,从基础到实战

    本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看

    黄小斜
  • 字符串、集合如何判断空值?看看成年人的正确操作

    在平时的开发中,基本上都会用到字符串判断空值和集合判断空值的处理,还记得在刚干开发的时候,写的代码在现在看起来是真的有点Hello World,那么这次分享两个...

    一个程序员的成长
  • 使用位运算、值交换等方式反转java字符串-共四种方法

    在本文中,我们将向您展示几种在Java中将String类型的字符串字母倒序的几种方法。

    字母哥博客

扫码关注云+社区

领取腾讯云代金券