点击上方“方志朋”,选择“设为星标”

回复”666“获取新整理的面试资料

作者:cipher

www.ciphermagic.cn/java8-builder.html

程序员经常会遇到灵魂拷问:你有对象吗?

没有,但我可以 new 一个!

public class GirlFriend {private String name;private int age;// 省略 getter & setter ...public static void main(String[] args) {GirlFriend myGirlFriend = new GirlFriend();myGirlFriend.setName("小美");myGirlFriend.setAge(18);}
}

没问题,老铁!但如果对象的属性太多,咋办?

public class GirlFriend {private String name;private int age;private int bust;private int waist;private int hips;private List<String> hobby;private String birthday;private String address;private String mobile;private String email;private String hairColor;private Map<String, String> gift;// 等等等等 ...// 省略 getter & setter ...public static void main(String[] args) {GirlFriend myGirlFriend = new GirlFriend();myGirlFriend.setName("小美");myGirlFriend.setAge(18);myGirlFriend.setBust(33);myGirlFriend.setWaist(23);myGirlFriend.setHips(33);myGirlFriend.setBirthday("2001-10-26");myGirlFriend.setAddress("上海浦东");myGirlFriend.setMobile("18688888888");myGirlFriend.setEmail("pretty-xiaomei@qq.com");myGirlFriend.setHairColor("浅棕色带点微卷");List<String> hobby = new ArrayList<>();hobby.add("逛街");hobby.add("购物");hobby.add("买东西");myGirlFriend.setHobby(hobby);Map<String, String> gift = new HashMap<>();gift.put("情人节礼物", "LBR 1912女王时代");gift.put("生日礼物", "迪奥烈焰蓝金");gift.put("纪念日礼物", "阿玛尼红管唇釉");myGirlFriend.setGift(gift);// 等等等等 ...}
}
GirlFriend{name='小美'
, age=18
, bust=33
, waist=23
, hips=33
, hobby=[逛街, 购物, 买东西]
, birthday='2001-10-26'
, address='上海浦东'
, mobile='18688888888'
, email='pretty-xiaomei@qq.com'
, hairColor='浅棕色带点微卷'
, gift={情人节礼物=LBR 1912女王时代, 生日礼物=迪奥烈焰蓝金, 纪念日礼物=阿玛尼红管唇釉}
}

GirlFriend 是很美,但写起来也太麻烦了吧。

说说缺点:实例化和设置属性分开,不好维护;变量名重复写。

莫慌,看法宝~

这里不再介绍其他 Builder 实现方式,直接祭出最实用的通用Builder:

适用于所有类,不需要改造原来类,不需要 lombok 插件支持。

先看看使用姿势:

public class GirlFriend {// 省略属性 ...// 省略 getter & setter ...// 为了演示方便,加几个聚合方法public void addHobby(String hobby) {this.hobby = Optional.ofNullable(this.hobby).orElse(new ArrayList<>());this.hobby.add(hobby);}public void addGift(String day, String gift) {this.gift = Optional.ofNullable(this.gift).orElse(new HashMap<>());this.gift.put(day, gift);}public void setVitalStatistics(int bust, int waist, int hips) {this.bust = bust;this.waist = waist;this.hips = hips;}public static void main(String[] args) {GirlFriend myGirlFriend = Builder.of(GirlFriend::new).with(GirlFriend::setName, "小美").with(GirlFriend::setAge, 18).with(GirlFriend::setVitalStatistics, 33, 23, 33).with(GirlFriend::setBirthday, "2001-10-26").with(GirlFriend::setAddress, "上海浦东").with(GirlFriend::setMobile, "18688888888").with(GirlFriend::setEmail, "pretty-xiaomei@qq.com").with(GirlFriend::setHairColor, "浅棕色带点微卷").with(GirlFriend::addHobby, "逛街").with(GirlFriend::addHobby, "购物").with(GirlFriend::addHobby, "买东西").with(GirlFriend::addGift, "情人节礼物", "LBR 1912女王时代").with(GirlFriend::addGift, "生日礼物", "迪奥烈焰蓝金").with(GirlFriend::addGift, "纪念日礼物", "阿玛尼红管唇釉")// 等等等等 ....build();}
}

看到了吗!实例化和属性设置在同一条语句执行,链式操作,一路点点点,清爽!

Talk is cheap, show me the code:

/*** 通用的 Builder 模式构建器** @author: CipherCui* @since 2019/8/29*/
public class Builder<T> {private final Supplier<T> instantiator;private List<Consumer<T>> modifiers = new ArrayList<>();public Builder(Supplier<T> instantiator) {this.instantiator = instantiator;}public static <T> Builder<T> of(Supplier<T> instantiator) {return new Builder<>(instantiator);}public <P1> Builder<T> with(Consumer1<T, P1> consumer, P1 p1) {Consumer<T> c = instance -> consumer.accept(instance, p1);modifiers.add(c);return this;}public <P1, P2> Builder<T> with(Consumer2<T, P1, P2> consumer, P1 p1, P2 p2) {Consumer<T> c = instance -> consumer.accept(instance, p1, p2);modifiers.add(c);return this;}public <P1, P2, P3> Builder<T> with(Consumer3<T, P1, P2, P3> consumer, P1 p1, P2 p2, P3 p3) {Consumer<T> c = instance -> consumer.accept(instance, p1, p2, p3);modifiers.add(c);return this;}public T build() {T value = instantiator.get();modifiers.forEach(modifier -> modifier.accept(value));modifiers.clear();return value;}/*** 1 参数 Consumer*/@FunctionalInterfacepublic interface Consumer1<T, P1> {void accept(T t, P1 p1);}/*** 2 参数 Consumer*/@FunctionalInterfacepublic interface Consumer2<T, P1, P2> {void accept(T t, P1 p1, P2 p2);}/*** 3 参数 Consumer*/@FunctionalInterfacepublic interface Consumer3<T, P1, P2, P3> {void accept(T t, P1 p1, P2 p2, P3 p3);}
}

这个示例最多支持三个参数的设置属性方法,也完全够用了。如果要扩展也很容易,依葫芦画瓢,添加多个参数的Consumer。

快用你的 Builder 建个对象吧~

热门内容:

  • 大批 IDEA 激活码到期之后的乱象...

  • 全面了解 Nginx 主要应用场景

  • 为什么微服务一定要有网关?

  • 那些在一个公司死磕了5-10年的人,最后都怎么样了?

  • 只有程序员才能读懂的西游记

  • 2020,搞个 Mac 玩玩!

  • 分布式与集群的区别究竟是什么?

  • 碰到Maven依赖冲突,想砸电脑?这个IDEA插件必须了解一下...

  • 2020年Java框架排行榜,谁居榜首?

  • SpringBoot+RabbitMQ ,保证消息100%投递成功并被消费(附源码)

最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

明天见(。・ω・。)ノ♡

你还在new对象吗?Java8通用Builder了解一下?相关推荐

  1. 你还在 new 对象吗?Java8 通用 Builder 了解一下?

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"加群"获取公众号专属群聊入口 来源:rrd.me/gtQTp 程序员经常会遇到灵魂拷问 ...

  2. C java new_你还在new对象吗?Java8通用Builder了解一下?

    程序员经常会遇到灵魂拷问:你有对象吗? 没有,但我可以 new 一个! public class GirlFriend { private String name; private int age; ...

  3. 并发加对象锁_通用并发对象池

    并发加对象锁 在本文中,我们将介绍如何在Java中创建对象池. 近年来,JVM的性能成倍增加,大多数类型的对象几乎都变得多余,从而提高了对象池的性能. 从本质上讲,对象的创建不再像以前那样昂贵. 但是 ...

  4. java emailbuilder 样式_Java8通用Builder了解一下

    程序员经常会遇到灵魂拷问:你有对象吗? 没有,但我可以 new 一个! public class GirlFriend { private String name; private int age; ...

  5. JVM - 写了这么多年代码,你还不知道new对象背后的逻辑?

    文章目录 对象创建流程 [类加载检查] [分配内存] 内存划分的两种方式 解决分配内存并发问题的两种方式 [初始化] [设置对象头] 对象的组成 对象头的两部分组成 [执行init方法] 总结一下 对 ...

  6. java 反射 new class_Java高级特性-反射:不写死在代码,还怎么 new 对象?

    反射是 Java 的一个高级特性,大量用在各种开源框架上. 在开源框架中,往往以同一套算法,来应对不同的数据结构.比如,Spring 的依赖注入,我们不用自己 new 对象了,这工作交给 Spring ...

  7. 这河里吗?Go 里边空指针还能调用对象方法!

    本篇是煎鱼回答记者,啊不是,回答读者的提问,内容分析的不错.注意文里的读者群不是我的,我就只有公众号,以文会友,看完想走就走,赞不赞的不重要,如果想了解哪方面内容可以直接留言或者私信. 最近在我们 G ...

  8. 对象池 GenericObjectPool 通用对象池

    透明代理的使用 在对后端的连接中使用对象池(backend是一个池子 里面是一个域名的连接) 使用需要用到的组件 GenericObjectPool.Config DefaultChannelGrou ...

  9. 笔记十三 :Egret拖拽对象与吸附对象(基于通用MVC框架)

    前言:拖拽对象是2D游戏中常用的一个功能,例如<植物大战僵尸>中种植植物的表现形式,拖拽植物卡片种植到相应的地点. 思路:在Egret中实现拖拽对象,需要用到TOUCH_MOVE事件的监听 ...

最新文章

  1. TensorFlow 强制使用CPU
  2. 【咸鱼教程】基于系统时间的计时器DateTimer(不受FPS影响)
  3. C++11 (多线程)并发编程总结
  4. nginx+keepalived高可用及双主模式
  5. Java机器学习库ML之十模型选择准则AIC和BIC
  6. 封条格式用word怎么打_大门封条格式用word怎么打
  7. 锐捷设备密码破解方法
  8. 二年级机器人伙伴看图写话_期末考试一二年级看图写话22篇,附范文!
  9. JS兼容性问题:window.locatin.href is not a function
  10. [复变函数]第16堂课 4.4 解析函数零点的孤立性及惟一性定理
  11. 任务栏流量监测工具 NetSpeedMonitor 在Windows 8下的安装使用
  12. latex数学符号加粗_LaTex数学公式符号整理
  13. 2020计算机考研英语国家线,2020考研英语国家分数线?
  14. java短链接_Java 网址短链接服务原理及解决方案
  15. 解决“windows已经阻止此软件因为无法验证发行者”方法
  16. 电力电子技术第二章总结
  17. k8s Webhook 准入控制应用实践
  18. HTML俄罗斯方块小游戏
  19. ZJOI2008 泡泡堂
  20. Fluent离散相模型分析操作简单实例

热门文章

  1. jQuery UI vs Kendo UI jQuery Mobile vs Kendo UI Mobile
  2. 【组队学习】【35期】吃瓜教程——西瓜书+南瓜书
  3. 【NCEPU】凌亮:Linux实践
  4. 【组队学习】【31期】水很深的深度学习
  5. 谢文睿:西瓜书 + 南瓜书 吃瓜系列 8. 软间隔与支持向量回归
  6. 怎样去掉 CSDN-Markdown 上传图片中的水印
  7. 【数据结构】顺序表的应用(1)(C语言)
  8. 【CTF】实验吧 The Flash-14
  9. 推荐 2个十分好用的 pandas 数据探索分析神器!
  10. 深度学习发展下的“摩尔困境”,人工智能又将如何破局?