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>() {@Overridepublic 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>() {@Overridepublic People get() {People people = new People() {@Overridepublic 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;}@Overridepublic String toString() {return "Person{" +"name='" + name + "'}'";}
}

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

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


  • 本文所有源代码点我
  • 更多设计模式学习点我或浏览博客设计模式专栏查看

参考文献

  • Design Patterns: Elements of Reusable Object-Oriented Software 1st Edition

JDK1.8 Consumer Supplier 什么意思相关推荐

  1. [彻底理解]JDK1.8 函数式接口 Consumer Supplier 以及 JAVA新纪元 λ表达式的到来

    JDK1.8 函数式接口 Consumer & Supplier 以及 JAVA新纪元 λ表达式的到来 背景什么的被吞了,直接进入主题 函数式接口(定义自己百度,一大堆) 因为看了一些关于JD ...

  2. 【JDK8语法新特性】:超全总结{lamda,stream,optional,新日期类API},JDK8对策略模式支持,可以直接贴代码运行测试。

    文章目录 Java8新特性 速度快 代码更少(增加了新的语法,lamda表达式)(主要) 强大的Stream API(主要) 便于并行 最大减少空指针异常(Optional API) 提供了线程安全的 ...

  3. 全站课-阶段二(Java SpringBoot API打造高级电商业务后端)

    项目目录 missyou ├─github │ └─wxpay │ └─sdk # 微信sdk └─lin└─missyou│ MissyouApplication.java # 启动类├─api│ ...

  4. 那些年,我们追过的java8

    那些年,我们追过的java8 9月份java9就要发布了,在8月的最后一天决定回顾一下java8那些惊天动地的变化,加深理解,共同进步. 我们都知道java与c++,c不同是一个为面向对象而生的语言, ...

  5. Java8函数式编程(1)--Principle

    核心概念 Java8是怎么支持函数编程的呢?主要有三个核心概念: 函数接口(Function) 流(Stream) 聚合器(Collector) 函数接口 关于函数接口,需要记住的就是两件事: 函数接 ...

  6. 将旧对象装箱可自动关闭

    从Java 7开始,我们可以使用try-with-resources并自动关闭任何实现Autocloseable接口的对象. 如果资源是 Autocloseable . 一些类需要一些总结,但不是Au ...

  7. 《Java8实战》笔记(03):Lambda表达式

    本文源码 Lambda 管中窥豹 可以把Lambda表达式理解为简洁地表示可传递的匿名函数的一种方式:它没有名称,但它有参数列表.函数主体.返回类型,可能还有一个可以抛出的异常列表. Lambda表达 ...

  8. java function void_Java8中你可能不知道的一些地方之函数式接口实战

    什么时候可以使用 Lambda?通常 Lambda 表达式是用在函数式接口上使用的.从 Java8 开始引入了函数式接口,其说明比较简单:函数式接口(Functional Interface)就是一个 ...

  9. 是清单 Dog List的子类 Animal ? 为什么Java泛型不是隐式多态的?

    我对Java泛型如何处理继承/多态感到困惑. 假设以下层次结构- 动物 (父母) 狗 - 猫 (儿童) 因此,假设我有一个方法doSomething(List<Animal> animal ...

最新文章

  1. Mybatis学习记录(二)----mybatis开发dao的方法
  2. linux内核函数kmalloc,Linux_Linux平台上几个常见内核内存分配函数,* kmallocPrototype:#incl - phpStudy...
  3. 修改正文中参考文献标注_论文写作中怎样正确插入参考文献,引用文献如何标注?...
  4. 何使用BERT模型实现中文的文本分类
  5. 修改html自带组件样式,能否直接在组件html上为组件根元素设置自定义class
  6. JavaScript-作用域和作用域链
  7. 使用java语言操作,如何来实现MySQL中Blob字段的存取
  8. loadrunner11下载
  9. php漂浮广告代码,js 居中漂浮广告_广告代码
  10. HCSE设计知识点50个
  11. 日本python程序员工资_年轻程序员赴日本工作有前途吗?
  12. Netty客户端断线重连
  13. 手机网页点击按钮给指定号码发送短信
  14. 内网搭建speedtest测速工具
  15. 用python做线性规划
  16. nrf51822裸机教程-SPI(主)
  17. C语言读写ini、json、csv文件
  18. 框图c语言程序,C语言程序设计框图
  19. win10 itunes更新ios系统异常 提示“未能恢复iPhone 发生未知错误(14)”
  20. 2016年10月9日 星期日 --出埃及记 Exodus 18:20

热门文章

  1. python中import os_python中import os什么意思
  2. 中点画线算法(计算机图形学)
  3. 7.0_[Java 面向对象]-类和对象
  4. 关于Dagger2的一些个人理解
  5. Windows10 桌面图标显示异常
  6. 矩阵奇异值分解与照片压缩、去噪
  7. android 带箭头的按钮,android自定义带箭头对话框
  8. 讯飞语音合成和百度语音合成,粘贴就能用
  9. 智能指纹挂锁方案—模组—西城微科
  10. 简单智能远程控制服务器课题