JDK1.8 Consumer & Supplier 什么意思

JDK1.8 函数式接口 Consumer & Supplier 以及 JAVA新纪元 λ表达式的到来

背景什么的被吞了,直接进入主题


函数式接口(定义自己百度,一大堆)

因为看了一些关于JDK1.8函数式接口的文章,发现基本上都是糊里糊涂一笔带过.所以就抽空赶紧整理了一下.

还是附上几个学习了解的传送门 :


Consumer 函数式接口

JDK 源码

/**
 * 接受单个输入参数并且不返回结果的操作。
 * 与大多数其他功能接口不同, Consumer预期通过副作用进行操作。
 *
 * @since 1.8
 */
@FunctionalInterface
public interface Consumer<T> {

    /**
     * 对给定的参数执行此操作。
     *
     * @param t the input argument
     */
    void accept(T t);

    /**
     * 返回一个组合的Consumer ,依次执行此操作,然后执行after操作。 
     * 如果执行任一操作会抛出异常,它将被转发到组合操作的调用者。 
     * 如果执行此操作会引发异常,则不会执行after操作。
     *
     * @param 此操作后执行的操作
     * @return 一个组成的 Consumer ,依次执行 after操作
     * @throws NullPointerException - if after is null
     */
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }

刚拿过来看的时候可能会有一些绕,但是我们换个角度来看一下.

Consumer 直译过来就是消费者的意思,那我们是不是可以理解成消费代码.既然他要消费,那我们就要给他提供代码.

来看一个简单的demo

public void testConsumer1() {
        Consumer<String> consumer = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s + "?");
            }
        };
        consumer.accept("李磊");
    }

输出结果

李磊?

简单解释一下

Consumer是一个接口,所以当我们直接使用的话,要实现其 accept()方法,而这个方法的参数,就是我们定义接口时候给到的泛型,这里给的是一个String类型,方法当中的内容,就是我们所谓的消费代码,当调用accept()方法时执行.

注意 : 也就是上面提到的通过副作用处理,我不清楚这个单词翻译的是否准确,看了很多博主和一些机器翻译都是这个意思,但我个人的理解意思,更趋近于说是通过侧面来解决问题.

再看一下 consumer.accept("李磊")这一句,这里便是真正的执行的地方,也就是调用的我们刚刚自行实现的accept()方法.

让我们继续刚刚的demo往下看

这种写法和上面在JDK1.8环境中是等价的. 主要就是利用到了1.8中的 λ 表达式.

    public void testConsumer1() {
        Consumer<String> consumer = s -> System.out.println(s + "?");
        consumer.accept("李磊");
    }

下面的例子均使用λ表达式完成

泛型为自定义对象时

public void testConsumerToSupplier() {
        Consumer<Person> consumer = person -> {
            person.setName("张颖");
            person.setSize(34);
        };
        Person person = new Person();
        consumer.accept(person);
        System.out.println("person = " + person);
    }

输入结果:

person = Person{name='张颖', size=34}

泛型为自定义接口时

public interface People {
    void come(Person person);
}
public void testConsumerAndInterfaceFunction() {
        Consumer<People> consumer = people -> {
            people.come(new Person("李四", 23));
            people.come(new Person("找钱", 34));
            people.come(new Person("孙俪", 45));
        };

        consumer.accept(this::print);
    }

    public void print(Person person) {
        System.out.println("person = " + person);
    }

输出结果

person = Person{name='李四', size=23}
person = Person{name='找钱', size=34}
person = Person{name='孙俪', size=45}

如果到了这里还没有明白怎么回事,我建议你亲自动手敲上那么一遍.真的,如果还不懂来杭州,我当面给你讲.


Supplier 函数式接口

还是一样,先看一下JDK源码

/**
 * 获得对象的一个函数式接口
 *
 * @since 1.8
 */
@FunctionalInterface
public interface Supplier<T> {

    /**
     * 得到一个对象
     *
     * @return 目标对象
     */
    T get();
}

这个是不是看起来很容易理解了,Supplier的意思是供应商,那我们是不是可以把他理解成一个商场,然后你告诉他你想要的东西是什么样子的,它是不是就会给你了.

来看一下这个简单的demo

void testSupplier1() {
        Supplier<String> supplier = () -> "这是你要的字符串";
        String str = supplier.get();
        System.out.println("str = " + str);
    }

运行结果:

str = 这是你要的字符串

继续自定义对象

void testSupplier2() {
        Supplier<Person> supplier = () -> {
            Person person = new Person();
            person.setName("张三");
            person.setSize(32);
            return person;
        };

        Person person = supplier.get();
        System.out.println("person = " + person);
    }

运行结果

person = Person{name='张三', size=32}

再来刺激的自定义接口

    void testSupplier3() {
        Supplier<People> supplier = new Supplier<People>() {
            @Override
            public People get() {
                People people = new People() {
                    @Override
                    public void come(Person person) {
                        System.out.println("person = " + person)
                    }
                };
                return people;
            }
        };

        People people = supplier.get();
        people.come(new Person("李四", 24));
    }

输出结果

person = Person{name='李四', size=24}

看好别眨眼,λ表达式的写法 下面的一行和上面的一堆是等价的

void testSupplier4() {
    Supplier<People> supplier = () -> person -> System.out.println("person = " + person);
    People people = supplier.get();
    people.come(new Person("李四", 24));
}

输出结果

person = Person{name='李四', size=24}

想必看到这你不光明白了 Supplier的用法,更清楚的λ表达式的用处了.


写在最后,写这篇文章的原因是因为在整理工厂模式的时候遇到的一些问题

工厂模式简单的是不能再简单了,但是随着技术的发展,也出现了一些新颖的工厂方法.CTS便是其中之一.

至于Consumer&Supplier应用在工厂模式的代码如下,因为比较特殊,写在了一起,想要亲自体检复制粘贴运行TTT类的main()方法即可

/**
 * @author lvgo
 * @version 1.0
 * @Description: CTS实现工厂模式
 * @date 18-8-24 下午3:57
 */
public interface CTS {

    static CTS getCts(Consumer<Peoples> consumer) {
        Map<String, Supplier<Persons>> map = new HashMap<>();
        consumer.accept(map::put);
        return person -> map.get(person).get();

    }

    Persons getPerson(String name);
}

interface Peoples {
    void come(String name, Supplier<Persons> personSupplier);
}

class TTT {
    public static void main(String[] args) {
        CTS cts = CTS.getCts(people -> {
            people.come("张三", () -> new Persons("张三"));
            people.come("李四", () -> new Persons("李四"));
            people.come("王五", () -> new Persons("王五"));
        });

        Persons person = cts.getPerson("王五");
        System.out.println("persons = " + person);
    }
}

class Persons {

    private String name;

    public Persons() {
    }

    public Persons(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + "'}'";
    }
}

CTS工厂模式说明: Consumer To Supplier 自造词,无处可寻,他处偶遇纯属抄袭;

通过Peoples接口的come()方法,可以动态在CTS工厂内添加person,然后使其具于生产该实例的能力.



参考文献

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值