• Java函数接口:Supplier


    之前我们一提到Java8新特性,两个常提的stream和Lambda表达式,实际还有一个大的方向就是函数接口。但是stream和Lambda表达式,使用场景也比较多,基本一推出来,基本日常场景就能用到。但是函数接口就不一样,他需要他自己的使用场景,如果不理解,只背他的定义,实际没啥帮助。这里我就通过介绍使用场景的方式来说一下Supplier函数接口。

    一 使用场景

    我们日常会用到泛型,java.util.function.Supplier 接口仅包含一个无参的方法: T get() 。用来获取一个泛型参数指定类型的对象数据。

    那就只有一个get方法,有什么可以用到的场景,其实就是封装对象,这里我有两个场景可以介绍一下。

    第一种,redis保存数据,大家都有共同的属性,过期单位和设置过期时间,但是里面的对象不确定,这里我们可以将对象以泛型的形式,作为suplier构成。

    public class RedisSupplier  {
    
        private int expire;
    
        private TimeUnit timeUnit;
    
        Supplier supplier;
    
        public int getExpire() {
            return expire;
        }
    
        public void setExpire(int expire) {
            this.expire = expire;
        }
    
        public TimeUnit getTimeUnit() {
            return timeUnit;
        }
    
        public void setTimeUnit(TimeUnit timeUnit) {
            this.timeUnit = timeUnit;
        }
    
        public Supplier getSupplier() {
            return supplier;
        }
    
        public void setSupplier(Supplier supplier) {
            this.supplier = supplier;
        }
    
        public RedisSupplier(int expire, TimeUnit timeUnit, Supplier supplier) {
            this.expire = expire;
            this.timeUnit = timeUnit;
            this.supplier = supplier;
        }
    
        public T get() {
            return this.supplier.get();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    第二种,就是我们工作流,对应taskid这些都是固定的,对应不同的工作流参数,我们需要一个泛型管理起来。

        protected abstract void updateDetail(Supplier> supplier, Long merchantId, boolean isApproval, InStorageOrderDO inStorageOrderDO, Attribute.ArticleAttribute attribute);
    
    • 1
    二 如何使用工作流

    看Supplier里面只有一个get方法,获取一个泛型对象,那怎么把这个对象塞进去。

    借助Lambda
    借助lambad表达式直接塞对象进去。

      Supplier str = () -> "ZP handsome.";
            System.out.println("lambda Supplier :" + str.get() );
    
    • 1
    • 2

    我们还可以借助对象里面的方法,进行调用。比如我们定义了一个makerMoney。

    package com.example.test.j8.supplier;
    
    /**
     * @Author: zhangpeng
     * @Description:
     * @Date: 2022/11/12
     */
    public class Person {
    
        private Integer age;
    
        private String name;
    
        public Person(){}
    
        public Person(Integer age, String name){
            this.age = age;
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    
        public String  makerMoney(){
            return "  make money for live.  ";
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    然后调用(实际::双冒号就是调用方法的意思)

            Supplier str1 = person::makerMoney;
            System.out.println(" Non static method Supplier :" + str1.get());
    
    • 1
    • 2

    构造方法
    构造方法是现实中用的最多的一种方式,向Supplier塞进对象。

      //真正使用场景,就是传参一个对象进去
            PersonSupplier ps1 = new PersonSupplier<>(18,"卖课",()->"嘎嘎噶韭菜" );
            System.out.println(" construction method Supplier : " + ps1.getSupplier().get());
    
    PersonSupplier ps2 = new PersonSupplier<>(18,"卖课",()->new WebSite("XX课程","高并发") );
            System.out.println(" construction method Supplier : " + ps2.getSupplier().get().getWebSiteName() + ps2.getSupplier().get().getTarget() );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    具体代码参见我的GitHub对应目录
    以上演示的完整代码

    扩展

    实际上和Supplier还有一个对应相反的一个函数接口,Consumer,听名字上可以这么区分,Supplier生产者,该接口定义一个无参的get方法,() -> T,如果不接受入参,直接为我们生产一个指定的结果,那么就可以用Supplier。

    生产一个指定的结果

    Conusmer消费者,该接口定义了一个void accept(T)的抽象方法,其函数描述符为 (T) -> void,如果你需要一个操作某一对象,但无需返回的的函数式接口,那么就可以使用Consumer接口。

  • 相关阅读:
    tomcat启动jvm内存设置
    8. shell正则表达式
    OptiCoupe 6:光学切割面板和型材切割优化[OptiCut]
    POJ 3185 The Water Bowls 反转+点灯游戏
    深度学习系列45:图像恢复综述
    论文4问O
    冠军斩获10万奖金!首届“域见杯”医检AI开发者大赛精彩落幕
    【网络编程套接字】基于TCP协议的网络程序
    A-Level商务模型介绍:波士顿矩阵
    论文阅读-Federated-Unlearning-With-Momentum-Degradation
  • 原文地址:https://blog.csdn.net/FeiChangWuRao/article/details/127842160