范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

函数式编程的思维转变从数据参数化到行为参数化

  为什么要了解函数式编程;函数式编程对哪些设计模式产生了影响;如何从数据参数化过渡到行为参数化;策略模式的三种实现方式。
  极客架构师——专注架构师成长。
  大家好,我是码农老吴。
  今天是我的《Java极客》系列分享的第一期。
  今天也是2022年的最后一天,经过多天的病毒折磨,刀片桑,咳嗽,浑身无力,都体验了一遍,终于在兔年到来之前,满血复活了。感谢大家的关心,提前一天,祝大家新年快乐,身体健康,职场顺利,万事大吉。
  兔年快乐
  古朗月行
  【作者】李白
  小时不识月,呼作白玉盘。
  又疑瑶台镜,飞在青云端。
  仙人垂两足,桂树何团团。
  白兔捣药成,问言与谁餐。
  蟾蜍蚀圆影,大明夜已残。
  羿昔落九乌,天人清且安。
  阴精此沦惑,去去不足观。
  忧来其如何,凄怆摧心肝。分享思路
  《Java极客》分享内容
  为什么要分享函数式编程
  函数式编程包含哪些内容
  案例说明-电商后台的商品过滤功能
  版本1 硬编码
  版本2 数据参数化
  版本3 方案1 串行化的多条件过滤
  版本3 方案2 并行化的多条件过滤
  走出思维死角——行为参数化
  版本4 基于策略模式
  版本5 基于匿名类的策略模式
  版本6 基于Lambda表达式的策略模式
  下期预告
  参考书籍《Java极客》分享内容
  《Java极客》这个系列,我将分享Java开发相关的几个比较重要的,有一定难度的专题内容,内容主要涉及:函数式编程,泛型编程,并发编程,JVM等。为什么要分享函数式编程
  一个最直接的原因,就是因为函数式编程,对我们目前正在分享的设计模式,其中的好几个设计模式,都产生了比较大的影响,比如策略模式,模板方法模式,观察者模式,责任链模式,工厂模式等等。为了方便大家,更好的学习函数式编程下的设计模式,我决定把Java中的函数式编程功能,系统的分享一下。函数式编程包含哪些内容
  众所周知,Java语言并不是天生的函数式编程语言,只是在新的时代需求下(大数据分析和CPU多核时代),Java语言,特别是Java8,发展出来的,支持函数式编程的新功能。
  内容主要包括:行为参数化,Lambda表达式,方法引用,流操作等等。
  今天,我们就从行为参数化开始。案例说明-电商后台的商品过滤功能
  电商后台,难免对商品进行各种查询,统计,大多数情况下,通过数据库就可以完成,如果数据量非常大的情况下,还会用上大数据系统。当然,如果具体到店铺级别,一般商品的数量是可控的,量级不会太大(10万级别,不超过百万),直接使用Java集合框架,在内存中直接对商品进行查询,过滤,统计等操作,也是比较简洁,高效的。由于函数式编程的流操作,主要是通过集合框架进行数据操作的。所以我们主要以集合框架对数据进行分析。
  商品实体类类图及代码如下:商品(SKU)类图
  package com.geekarchitect.javageek.module001.demo01;  import lombok.Data;  /**  * @author 极客架构师@吴念  * @createTime 2022/12/29  */ @Data public class SKU {     private Long id;     private String name;     private Long categoryId;     private String categoryName;     private Double price;     private Long shopId;     private String shopName;     private int sales;//销售量     private int stock;//库存量      public SKU() {     }      public SKU(Long id, String name, Long categoryId, String categoryName, Double price, Long shopId, String shopName, int sales, int stock) {         this.id = id;         this.name = name;         this.categoryId = categoryId;         this.categoryName = categoryName;         this.price = price;         this.shopId = shopId;         this.shopName = shopName;         this.sales = sales;         this.stock = stock;     } }
  模拟数据如下:package com.geekarchitect.javageek.module001.demo01;  import org.assertj.core.util.Lists;  import java.util.List;  /**  * @author 极客架构师@吴念  * @createTime 2022/12/29  */ public abstract class BaseTest {     List generatorSKU() {         SKU sku01 = new SKU(1L, "华为MateBook X", 1L, "笔记本", 10000D, 1L, "华为旗舰专卖店", 1000, 1000);         SKU sku02 = new SKU(2L, "华为MateBook pro", 1L, "笔记本", 11000D, 1L, "华为旗舰专卖店", 1000, 1000);         SKU sku03 = new SKU(3L, "华为MateBook D", 1L, "笔记本", 12000D, 1L, "华为旗舰专卖店", 1000, 1000);         SKU sku04 = new SKU(4L, "HUAWEI Mate 50", 2L, "手机", 12000D, 1L, "华为旗舰专卖店", 1000, 1000);         SKU sku05 = new SKU(5L, "HUAWEI Mate 50 PRO", 2L, "手机", 12000D, 1L, "华为旗舰专卖店", 1000, 1000);         SKU sku06 = new SKU(6L, "HUAWEI Mate 50E", 2L, "手机", 12000D, 1L, "华为旗舰专卖店", 1000, 1000);         return Lists.newArrayList(sku01, sku02, sku03, sku04, sku05, sku06);     } }
  需求1 查询商品分类属于"笔记本"的商品
  也就是商品的categoryName属性,属性值为"笔记本"的商品。版本1 硬编码SKUService
  这版代码,是需求的最直接的体现,整个方法,入参sourceSkuList中包含的是待查询的商品信息,返回值filteredSkuList集合中,包含了符合查询条件的商品。
  如果商品的CategoryName equals "笔记本",就把它添加到结果集合中。
  很简单吗,但是除了初学者,大家一般不会这么编码,至少大家能想到,这次要查询"笔记本",下次可能查询的就是别的了,所以"笔记本"不能硬编码,应该提取为一个参数。
  这就要看下版代码了。
  测试代码-SKUServiceTest
  运行结果
  版本2 数据参数化SKUService
  这版代码,比较符合实际工作中的常见编程习惯。把要查询的条件,设置为参数,至少能适应一定的需求变化,但是如果需求查询的不是商品的分类(categoryName),而是别是什么呢,比如价格,我们该如何应对呢。
  测试代码-SKUServiceTest
  运行结果
  略需求2 查询商品分类属于"笔记本",价格大于10000的商品
  这次我们的查询条件有两个,既要是笔记本,又要是价格大于1万。如何实现这个需求呢,对于两个查询条件。我们该如何处理呢,至少可以有两个思路。版本3 方案1 串行化的多条件过滤SKUService
  这版本代码,是大多数人能想到的解决方案,两个查询条件,就定义两个参数,过滤的时候,两个条件先后执行。在大多数的情况下,这个方案没有太大问题,但是在多核时代下,这种方案的局限性就很明显,因为不论有多少个条件,每个商品,都必须串行的执行所有的查询条件。如果要发挥多核时代,CPU的性能,就需要尝试下面的思路了(注意,这种解决方案,如果非要支持并发执行也不是不可能,只是相对下面的解决方案,不太方便罢了)
  测试代码-SKUServiceTest
  版本3 方案2 并行化的多条件过滤SKUService
  多个查询条件,如果要实现并行化的处理,每个查询条件可以独立进行数据过滤。所以,我们实现了两个数据过滤的方法。
  测试代码-SKUServiceTest
  在我们的测试代码中,我并没有真的并行执行这两个查询条件,而是一个执行完之后,再接着执行另外一个,从性能上看,应该还不如方案1,但是它提供了一种可能性,一种并发处理的可能性。我们自己如果要实现并行化的处理,要么直接编写多线程代码,要么使用线程池,代码都简单不了(我在并发编程的系列分享中,会有相关分享)。后面我们要分享的并行化的流操作,会直接帮助我们完成这个工作。
  走出思维死角
  前面我们对于两个需求,三个版本的解决方案,里面都存在一个思维定势,那就是数据参数化,我们要根据商品分类和价格查询商品,我们的参数,传递的就是商品分类的名称和价格这两个参数。我们能不能走出这个思维死角,换个思路呢。
  我们的查询条件是,商品分类的名称是否等于"笔记本",价格是否大于"1万",前面我们的目光都聚焦在"笔记本"和"1万"这些数据上,而忽略了"是否等于","是否大于"这两个词,它们代表的是动作,是行为。我们能不能更直接一些,把行为参数化呢。
  数据参数化,大家比较好理解,而行为参数化,在面向对象的Java语言中,不太直接,如果我们要传递一个行为(或者说传递一个方法),就只能通过传递对象,来间接的传递方法。
  我们看下面的方案。版本4基于策略模式
  接口及类
  SKUFilterStrategy:商品过滤接口
  CategoryNameFilterStrategy:根据商品分类过滤商品
  PriceGreaterThanFilterStrategy:根据价格过滤商品
  SKUServiceV2:商品过滤服务类
  SKUFilterStrategy接口:商品过滤策略接口,返回值为boolean,表示商品是否符合我们的过滤条件。
  CategoryNameFilterStrategy:商品过滤策略,判断商品分类是否属于"笔记本"。
  PriceGreaterThanFilterStrategy:商品过滤策略,判断商品价格是否大于1万。
  SKUServiceV2:商品过滤服务类
  filterSKUByStrategy()方法,根据商品过滤策略,对集合中的商品进行过滤。这里使用了策略模式,使得过滤商品的策略,可以无限的扩展,而这个方法,不需要进行任何修改,真正的符合开闭原则,对扩展开放,对修改关闭。
  还有一点,很重要的就是,我们传递的参数SKUFilterStrategy skuFilterStrategy,它是一个对象,而我们在方法中使用的,是这个对象的filter方法。这就是在Java这种面向对象的语言中,需要传递方法(行为)的一种间接的方案,通过传递不同的对象,来实现传递不同的方法。
  有没有更直接的方案呢,我们前面定义的CategoryNameFilterStrategy和PriceGreaterThanFilterStrategy,看起来有些大材小用,或者说有些繁琐。
  能不能更简单一些,在Java8以前,函数式编程还没有出来之前,我们还有一种选择,那就是匿名类了。/**  * @author 极客架构师@吴念  * @createTime 2022/12/29  */ public class SKUServiceV2 {     private static final Logger LOG = LoggerFactory.getLogger(SKUServiceV2.class);      public List filterSKUByStrategy(List sourceSkuList, SKUFilterStrategy skuFilterStrategy) {         List filteredSkuList = new ArrayList<>();         for (SKU sku : sourceSkuList) {             if (skuFilterStrategy.filter(sku)) {                 filteredSkuList.add(sku);             }         }         return filteredSkuList;     } }测试代码
  运行结果
  版本5基于匿名类的策略模式
  这次我们要使用基于匿名类的策略模式,所以只定义了策略接口,策略实现类一个都没有。测试代码
  由于商品的过滤条件,一般都是临时性的,我们专门定义一个类,有些累赘,而直接使用匿名类,则更直接一些。
  但是,大家有没有发现,即使使用了匿名类,代码好像也没简化多少,只不过少了个类名罢了。能不能更简单一些,下面我们的主角就要上场了。
  运行结果
  版本6基于Lambda表达式的策略模式
  这次我们要使用Java函数式编程中的lambda表达式,来实现策略模式,策略接口也是不能少的,策略实现类当然,也不需要。测试代码
  我们的主角登场了,使用了Lambda表达式,代码精简了不少,所有的官样代码都没有了。而且最为重要的一点,就是我们实现了真正的行为参数化,我们在参数中,直接传递的就是方法中的代码片段。而没有传递对象。这就是函数式编程的一个重要特点。那么这里的代码,为什么要这么写,语法是什么样的,还可以怎么写,这就是我们下一期要详细讲解的内容了。
  运行结果
  下期预告
  本期我们从数据参数化到行为参数化,从普通的策略模式,到匿名类的策略模式,再到基于Lambda表达式的策略模式,带领大家走进了Java函数式编程的大门,下期,我们就详细的聊聊Lambda表达式的语法规则,应用技巧以及它的底层原理。参考书籍
  《Java 8 in Action》
  《 On Java 8 》

贾乃亮李小璐晒照为女庆生,10岁甜馨长成大人模样,越来越像妈妈头条创作挑战赛10月23日是甜馨的10岁生日,下午晚些时候,贾乃亮也主动在微博上晒出了与女儿的合影,并甜蜜的表示祝天天拿捏我的大宝贝儿生日快乐。照片中,甜馨穿着居家服翘着二郎腿悠闲吸毒风波后,30岁的张一山真的凉了近日,有媒体拍到张一山和一位美女一起去酒吧,第二天一起从公寓出门,女生还送张一山到机场,甚至两人在车内拥吻的照片,引起张一山新恋情的猜测。但其实这不是张一山近期第一次被拍到这样的桃42岁张柏芝被曝怀四胎,这一次,请别再骂她了大家好,我是悠姐!42岁张柏芝又被曝怀四胎了。前两天,她在直播带货时,穿着宽松却难掩凸起的小腹。有网友猜测,这肚子已经怀孕有6个月了。没多久网上还有知情人证实,确实是怀孕了。这不是贾乃亮晒女儿生日照,10岁甜馨颇有公主范,完美继承父母高颜值学生教育是重中之重,更是每个家庭都很重视的问题,而学生的教育源于多方面,比如教师同学朋友以及学校等,其中家长也占据着重要的因素。良好的家庭教育对学生而言,要比教师教育更为重要,而家王者荣耀7周年庆典开启,全英雄皮肤福利来袭王者荣耀正式服在本周更新全新版本后,也迎来了七周年的庆典活动,本次将会开启一场全新的月桂币获取任务,目前也被不少的玩家们称为全球甄选首款联动皮肤王昭君星穹之声正式登场。此次王者还是LOL合同的神!WBG起诉RNG冲上韩网热搜第一,为何RNG总被起诉?前言自从电竞元年以来,随着资本的涌入,我们LPL近年来也是出现了许多新的银河战舰。而要说当下人气最高的新兴银河战舰,那莫过于拿下了shy哥的WBG了。但是相信对于一个老玩家老观众来王者走位如何练习以下内容由自己总结其实大多数走位是对于敌方技能的预判1。熟悉各种英雄技能2。把自己带入敌方英雄,如果我是对方下一步会怎么做3。可以玩一些高机动性的英雄如露娜,马超,司马懿,(安琪拉首款原神定制手机将发布,亮点太多让人惊喜,网友表示没白等原神这游戏,就算大家没玩过,肯定也听说过。这款游戏自上线后便成为了全球爆款手游,受到了众多玩家的追捧和喜爱,游戏的每一次版本更新都能引起巨大的轰动,新上架的限定角色基本都能在多国流疯狂骑士团寻宝之旅小技巧本文首发疯狂攻略组公众号,未经授权禁止抄袭文章转载至其它平台。哈喽,小伙伴们你们好,我是你们的小编半夏,疯狂骑士团是一款非常热门的高人气游戏,游戏以精美的画面,丰富的剧情,流畅的操吃鸡被封印的6套衣服,同样是动物园,却有着天壤之别欢迎诸位小伙伴们来到天哥开讲的吃鸡小课堂自从和平精英里出现了一系列动物元素的皮肤后,就被玩家冠以了和平动物园的绰号,什么猫狗熊羊牛等一应俱全,完全可以说是名副其实。然而来到一脉相承王者荣耀七周年庆典即将开启,文化弘扬道路再次启程转眼之间,王者荣耀陪伴我们已经七年了。从刚开始看着别人视频学出装连招,到现在每个赛季尝试冲刺王者,王者荣耀几乎成了我们生活中不可分割的一部分。从虚拟的互联网到真实的世界,王者荣耀一
河北前首富栽了?曾给员工发宝马,如今欠债2000亿,钱花哪了2021年,各家房地产企业纷纷暴雷。在恒大爆出负债1。96万亿的骇人消息之前,早有另一家地产企业陷入了债务危机。2021年2月1日,华夏幸福主动承认公司累计金融债务高达2000多亿河北与内蒙古辖区调整,河北省的4个县,为何给了内蒙古在前面的文章中,和大家聊了一系列河北省和周边地区变迁的发展历程,今天给大家聊一聊河北省和内蒙古自治区的区划变迁,在上世纪五六十年代,河北省和内蒙古自治区之间,就有过一系列的区划调整老照片1907年九十年代的河北秦皇岛秦皇岛地处河北东北部南临渤海,因秦始皇东巡至此派人入海求仙而得名,是中国唯一一个因皇帝帝号而得名的城市!1907年的孟姜女庙1941年孟姜女庙1930年的老龙头三十年代的天下第一关捕捉儿童敏感期之心得体会2022。8古话说三岁看大,七岁看老,儿童的教育关乎着他一生的发展和幸福成长。特别是06岁的早期教育,作为人生教育的奠基期,萌芽期,更显得尤为重要。而蒙氏早教,是在探寻儿童心理发展我国儿童因用错药导致耳聋已达30万!家里这些药,别再给孩子吃了近来,央视公布的一则公益短片让无数家长为之警惕。短片中,小女孩浠诺用手语向大家讲述了三年前因为生病,被家长错误用药导致耳聋,从此再也感受不到任何声音,进入了一个无声世界的事情由于家翠林云庄游记寻找乐谷的儿童印记翠林云庄乡村乐园位于城阳区棘洪滩街道东毛家庄社区,是一个融合旅游农业林业文化餐饮娱乐以及研学旅行等多功能为一体的田园综合体项目。园区设置森林体验区农事体验区森林度假区大棚休闲区拓展如何跟着孩子一起成长我家对门住着一位很厉害的女人,之所以说她厉害,是因为我很羡慕她,我儿子和她家的老四是玩伴,我跟她的关系也不错,我不知道她叫什么名字,我平时都称呼她橙子妈妈。对她我既羡慕,又佩服。说宝宝具有高智商的3个表现,哪怕只有一种,孩子将来更容易有出息头条创作挑战赛大家好,我是张女子育儿!还记得小时了了,大未必佳的故事么?虽然说孩子小时候聪明,长大了就不聪明,这是悖论,我们不应该相信。但孩子是否聪明,其实很多时候,从小时候,就可换帅如换刀?升班马都是王者,国安遇上7轮不败的绿城凶多吉少北京时间9月6日,晚上1930分,中超第16轮,北京国安将在日照主场迎战升班马浙江绿城。虽说换帅如换刀,但北京国安面对浙江绿城恐怕还是凶多吉少,因为新赛季的升班马都是王者。广州队换什么是无缝准镜面?摩托罗拉motorazr2022将其完美诠释给用户不断创新,才能有更大的突破,在折叠屏技术上,摩托罗拉从未输过,前几年为大家带来了水滴屏,今年又在新款motorazr2022上为大家带来了无缝准镜面,可谓是画龙点睛,赢得了更多用户姓氏与名字完美搭配张姓宝宝名字男孩名字张文希张少珵张皓楠张芊屹张璟锟张珂逸张书岩张翎尧张栩铮张若榛张翌瑄张禹珵女孩名字张屿乐张诗琪张奕姌张璟悦张叶芯张卿莀张莉然张兴萌张锦诺张萱仪张熙颖张恩夕王姓宝宝