java函数式编程及Consumer、Supplier、Function、Predicate四大接口

一、什么是函数式编程?

在维基百科中给出了详细的定义,函数式编程(英语:functional programming)或称函数程序设计,又称泛函编程,是一种编程范型,它将电脑运算视为数学上的函数计算,并且避免使用程序状态以及易变对象。函数编程语言最重要的基础是λ演算(lambda calculus)。而且λ演算的函数可以接受函数当作输入(引数)和输出(传出值)。

二、函数式编程的优点

在函数式编程中,由于数据全部都是不可变的,所以没有并发编程的问题,是多线程安全的。可以有效降低程序运行中所产生的副作用,对于快速迭代的项目来说,函数式编程可以实现函数与函数之间的热切换而不用担心数据的问题,因为它是以函数作为最小单位的,只要函数与函数之间的关系正确即可保证结果的正确性。

函数式编程的表达方式更加符合人类日常生活中的语法,代码可读性更强。实现同样的功能函数式编程所需要的代码比面向对象编程要少很多,代码更加简洁明晰。函数式编程广泛运用于科学研究中,因为在科研中对于代码的工程化要求比较低,写起来更加简单,所以使用函数式编程开发的速度比用面向对象要高很多,如果是对开发速度要求较高但是对运行资源要求较低同时对速度要求较低的场景下使用函数式会更加高效。

三、函数式编程的缺点

由于所有的数据都是不可变的,所以所有的变量在程序运行期间都是一直存在的,非常占用运行资源。同时由于函数式的先天性设计导致性能一直不够。虽然现代的函数式编程语言使用了很多技巧比如惰性计算等来优化运行速度,但是始终无法与面向对象的程序相比,当然面向对象程序的速度也不够快。

函数式编程虽然已经诞生了很多年,但是至今为止在工程上想要大规模使用函数式编程仍然有很多待解决的问题,尤其是对于规模比较大的工程而言。如果对函数式编程的理解不够深刻就会导致跟面相对象一样晦涩难懂的局面。

四、consumer

Consumer接口的源码只有两个方法,一个方法用来接收入口参数,另外一个是为了实现流式操作:

五、Supplier

upplier 接口是一个供给型的接口,其实,说白了就是一个容器,可以用来存储数据,然后可以供其他方法使用的这么一个接口,是不是很明白了,如果还是不明白,看看下面的例子,一定彻底搞懂!
/**
     * Supplier接口测试2,使用需要Supplier的接口方法
     */
    @Test
    public void test_Supplier2() {
        Stream stream = Stream.of(1, 2, 3, 4, 5);
        //返回一个optional对象
        Optional first = stream.filter(i -> i > 4)
                .findFirst();

        //optional对象有需要Supplier接口的方法
        //orElse,如果first中存在数,就返回这个数,如果不存在,就放回传入的数
        System.out.println(first.orElse(1));
        System.out.println(first.orElse(7));

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

        Supplier supplier = new Supplier() {
            @Override
            public Integer get() {
                //返回一个随机值
                return new Random().nextInt();
            }
        };

        //orElseGet,如果first中存在数,就返回这个数,如果不存在,就返回supplier返回的值
        System.out.println(first.orElseGet(supplier));
    }

其他 Supplier 接口

除了上面使用的 Supplier 接口,还可以使用下面这些 Supplier 接口。 IntSupplier 、DoubleSupplier 、LongSupplier 、BooleanSupplier,使用方法和上面一样。

六、Predicate 接口

Predicate 接口是一个谓词型接口,其实,这个就是一个类似于 bool 类型的判断的接口,后面看看就明白了。

/**
     * Predicate谓词测试,谓词其实就是一个判断的作用类似bool的作用
     */
    @Test
    public void test_Predicate() {
        //① 使用Predicate接口实现方法,只有一个test方法,传入一个参数,返回一个bool值
        Predicate predicate = new Predicate() {
            @Override
            public boolean test(Integer integer) {
                if(integer > 5){
                    return true;
                }
                return false;
            }
        };

        System.out.println(predicate.test(6));

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

        //② 使用lambda表达式,
        predicate = (t) -> t > 5;
        System.out.println(predicate.test(1));
        System.out.println("********************");

    }

undefined

/**
     * Predicate谓词测试,Predicate作为接口使用
     */
    @Test
    public void test_Predicate2() {
        //① 将Predicate作为filter接口,Predicate起到一个判断的作用
        Predicate predicate = new Predicate() {
            @Override
            public boolean test(Integer integer) {
                if(integer > 5){
                    return true;
                }
                return false;
            }
        };

        Stream stream = Stream.of(1, 23, 3, 4, 5, 56, 6, 6);
        List list = stream.filter(predicate).collect(Collectors.toList());
        list.forEach(System.out::println);

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

    }
public static void main(String[] args) {
       System.out.println(commonMethod(doError1));
       System.out.println(commonMethod(doError2));
   }

   public static String  commonMethod(Supplier doError){
       try {
           System.out.println("do Somthing");
           throw new Exception();
       } catch (Exception e) {
           log.error("error happen");
           return doError.get();
       }
   }

  private static Supplier doError1 = () -> {
       System.out.println(" do error1");
       return "erro1";
   };

  private static Supplier doError2 = () -> {
       System.out.println(" do error2");
       return "erro2";
   };

七、Function 接口

Function 接口是一个功能型接口,它的一个作用就是转换作用,将输入数据转换成另一种形式的输出数据。

public static void main(String[] args) {
        applyTest();
        andThenTest();
        composeTest();
        test();
    }

    //1、apply 示例
    private static void applyTest() {
        //示例1:利用lambda方式实现一个funciton,将String转换为Integer
        Function function = x -> Integer.parseInt(x);
        Integer a = function.apply("100");
        System.out.println(a.getClass());
    }

    //2、andThen 示例——实现一个函数 y=10x + 10;
    private static void andThenTest() {
        //先执行 10 * x
        Function function2 = x -> 10 * x;
        //通过andThen在执行 这里的x就等于上面的10 * x的值
        function2 = function2.andThen(x -> x + 10);
        System.out.println(function2.apply(2));
    }

    //3、compose 示例-实现一个函数 y=(10+x)2
    private static void composeTest() {
        Function function3 = x -> x * 2;
        //先执行 x+10 在执行(x+10)*2顺序与上面相反
        function3 = function3.compose(x -> x + 10);
        System.out.println(function3.apply(3));
    }

    //4、综合示例
        //使用compose()、andThen()实现一个函数 y=(10+x)*2+10;
    private static void test() {
      //真正执行的第二步
      Function function4 = x -> x * 2;
      //真正执行的第一步
      function4 = function4.compose(x -> x + 10);
      //真正执行的第三步
      function4 = function4.andThen(x -> x + 10);
      System.out.println(function4.apply(3));
    }
/**
     * 函数型接口:Function
     */
    @Test
    public void test3 () {
        String s = strOperar(" asdf ", x -> x.substring(0, 2));
        System.out.println(s);
        String s1 = strOperar(" asdf ", x -> x.trim());
        System.out.println(s1);
    }

    /**
     * 字符串操作
     * @param str 需要处理得字符串
     * @param fun Function接口
     * @return 处理之后得字符传
     */
    public String strOperar(String str, Function fun) {
        return fun.apply(str);
    }

除了上面使用的 Function 接口,还可以使用下面这些 Function 接口。 IntFunction 、DoubleFunction 、LongFunction 、ToIntFunction 、ToDoubleFunction 、DoubleToIntFunction 等等,使用方法和上面一样。

Original: https://www.cnblogs.com/yuluoxingkong/p/16409372.html
Author: yuluoxingkong
Title: java函数式编程及Consumer、Supplier、Function、Predicate四大接口

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/538130/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 2.7w字!Java基础面试题/知识点总结!(2021 最新版)

    这篇《Java 基础知识总结》是 JavaGuide 上阅读量最高的一篇文章,由于我对其进行了重构完善并且修复了很多小问题,所以,在博客园再同步一下! 文章内容比较多,目录如下: …

    Java 2023年6月9日
    062
  • java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverter

    在构建项目的时候使用的是jdk11,项目访问时报错 故障原因 使用了jdk版本过高 解决:直接在pom.xml中添加如下依赖可以解决(也可以试试降低jdk的版本) javax.xm…

    Java 2023年5月29日
    070
  • 面经

    本文收集最近遇到的好问题,保持学习,保持进步。 数据结构 树的深度优先和广度优先的算法实现 数据库的联合索引的底层实现 map 如何保证顺序 谈谈 HashMap 的源码 谈谈如何…

    Java 2023年6月8日
    080
  • 关于IDEA调试的一些基本操作

    一. 怎么开启断点调试? 随着开发的深入,越来越觉得高效的调试方法是多么的重要了,但我们一般上来就是敲一些代码,谁会去静下心来学一些看似没什么用的调试技巧呢?但这恰恰就是新手和老手…

    Java 2023年6月16日
    075
  • 什么是DevOps?为大家都在用DevOps

    摘要:什么是DevOps?为大家都在用DevOps,随着市场竞争的加剧,对企业的软件交付速度提出了更高的要求。像大家熟悉的大厂也不例外,落地DevOps、实现高效交付成为了企业共同…

    Java 2023年6月8日
    089
  • Java中代码块的理解

    静态、实例代码块 静态代码块,在类加载之前会加载一次,可以用来初始化静态资源 实例代码块,每次调用构造器初始化对象的时候,都要执行一次。其实质是放到构造器方法中执行。可以用来初始化…

    Java 2023年6月15日
    049
  • JDBC:加载数据库驱动、连接数据库(详细讲解)

    加载数据库驱动: 1)由于Java是一个纯面向对象语言,任何事物在其中都必须抽象成类或者类对象,数据库也不例外,JDBC同样也把数据库抽象成面向对象的结构; 2)JDBC将整个数据…

    Java 2023年6月5日
    0110
  • SpringCloudAlibaba项目之Sentinel流量控制

    SpringCloudAlibaba随笔目录 一、SpringCloudAlibaba项目之父工程搭建 二、 SpringCloudAlibaba项目之Nacos搭建及服务注册 三…

    Java 2023年6月5日
    064
  • 正则表达式详解

    正则表达式学习过程中最容易产生的误会 如果匹配成功则返回匹配成功的字符串,这个匹配成功的字符串很多人认为是整个存在目标值的整个字符串 如,abcd中我匹配abc,则返回结果为abc…

    Java 2023年6月7日
    082
  • Spring bean的作用域

    The scope of this bean: typically "singleton" (one shared instance, which will b…

    Java 2023年5月30日
    086
  • Spring(一):简介

    一、什么是Spring 广义上的 Spring 泛指以 Spring Framework 为核心的 Spring 技术栈。 经过十多年的发展,Spring 已经不再是一个单纯的应用…

    Java 2023年6月15日
    055
  • Error response from daemon: oci runtime error: container with id exists

    Error response from daemon: oci runtime error: container with id exists 序 常见问题之Docker——Err…

    Java 2023年6月5日
    049
  • Spring AOP 切点切面

    Spring AOP 切点切面 https://www.jianshu.com/p/94879042db88 https://www.jianshu.com/p/994027425…

    Java 2023年5月30日
    069
  • 在spring中配置time-zone=GMT+8无效、不生效解决方案

    spring.jackson.date-format=yyyy-MM-dd HH:mm:ss spring.jackson.time-zone=GMT+8 不起作用???不生效??…

    Java 2023年5月30日
    083
  • 项目版本管理Git使用详细教程

    前言 记得刚开始做项目开发的时候都是一个人完成一个项目,单打独斗的开发,也不知道什么是团队开发,没有这个概念,随着工作后来知道公司里项目都是团队开发,这个时候这么多人怎么开发一个项…

    Java 2023年6月13日
    087
  • Java项目调试技巧及版本控制

    开发项目中,调试是必不可少的。本篇博客的代码举例均为该系列博客涉及的项目:社交网站后端项目开发日记(一)本篇博客从以下4个方面介绍项目调试技巧: 响应状态码的含义 服务端断点调试技…

    Java 2023年6月7日
    065
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球