kotlin高阶函数实战&DSL入门

传统函数演示:

这里以电视节目“非诚勿扰”为例,男人去从一大堆美女当中挑选出自己中意的对象,比如台上有24位妹子,其档案如下:

接下来第一个男嘉宾出场啦,如下:

下面用代码来实现一下,比较简单:

先定义一个妹子的实体:

然后入库所有妹子的资料信息,这里直接用一个集合来表示,如下:

接着男嘉宾上场开始搜寻,第一个出场的只想找来自河南的妹子,用代码来满足需求如下:

上面的实现比较简单,也是第一时间能想到的,而查找某个地区妹子可能未来还有其它人需要使用,所以将其这个通用的行为封装到Girl中,如下:

这样就可以满足各种指定地区妹子的过滤了,如下:

传统需求实现的缺点:

接下来第二个男嘉宾出场啦,如下:

so easy嘛,再弄一个方法来根据年龄过滤,如下:

调用之:

接着第三个男嘉宾出场了,如下:

明显这位要求就多了,实现依然简单,基于之前的再copy改改就可以实现了,如下:

编译运行:

其中在kotlin中多个条件还可以这样写,如下:

ok,接着第四个男嘉宾出场了,如下:

貌似跟第三个男嘉宾的要求差不多,只不过这位是喜欢年纪大的,没关系,也可以轻松满足,只需基于第三个函数中加一个flag参数既可,如下:

接着还可能有以下其它需求的:

那是不是Girl这个类中存在大量的copy不断满足各种需求的代码,来一个需求就得增加一个对应的函数,可维护性就变得非常之差,那如何解决这类问题呢?就是用高阶函数,将其行为参数化,也就是方法传递的不再是值,而是具体的行为,其这在Java8中已经详细学习过了,下面就来在kotlin中也来学习下如何用高阶函数来更加便捷的解决上面各种各样的需求。

map,filter,groupBy,minBy,maxBy,find,any等:

对于什么是高阶函数在之前的学习中已经学过了,这里再总结一下:一个用函数作为参数或者返回值的函数,那下面通过一系列的实验来体会一下使用高阶函数的便捷性,还是以上面找妹子为例:

minBy、maxBy:

找年龄最大的妹子,先用传统的方式做肯定是需要这样做,如下:

比较繁琐,接着来看一下采用maxBy的高阶函数是如何做的:

其代码量一下就少了,那maxBy为啥是高阶函数叫?查看一下它的定义便知:

好,接下来需求变更,需要找出高度最高的妹子,利用了高阶函数之后,一切变得是那么的容易,如下:

那如果反过来找出最小的呢?那就改用minBy呗,如下:

filter:过滤特定条件

直接上代码,不多解释,用它来找年龄大于18、身高在168之上的妹纸,具体代码如下:

编译运行:

[Girl(name=笑笑, age=19, height=175, address=河南), Girl(name=玲儿, age=23, height=169, address=广东), Girl(name=环环, age=25, height=172, address=安微), Girl(name=胖嘟嘟, age=32, height=180, address=河北), Girl(name=乔乔, age=35, height=180, address=广东), Girl(name=月儿, age=25, height=178, address=吉林), Girl(name=花儿, age=21, height=183, address=山东), Girl(name=S小糖, age=49, height=190, address=新疆), Girl(name=棒棒糖, age=23, height=172, address=浙江)]

此时条件又发生变化了,需查找年龄大于18并且小于25、身高在168之上的妹纸,使用了高阶函数之后应对这些需求是如此容易,如下:

编译运行:

[Girl(name=笑笑, age=19, height=175, address=河南), Girl(name=玲儿, age=23, height=169, address=广东), Girl(name=花儿, age=21, height=183, address=山东), Girl(name=棒棒糖, age=23, height=172, address=浙江)]

另外看一下fiilter函数的定义:

map:

如果说要将妹子的所有名字都映射到一个集合里,利用map这个高阶函数做非常之简便,下面看下:

编译运行:

[依儿 : 18 , 笑笑 : 19 , 小百合 : 17 , michel : 22 , 猫咪 : 28 , 玲儿 : 23 , 环环 : 25 , 胖嘟嘟 : 32 , 乔乔 : 35 , 小可爱 : 27 , 一生有你 : 22 , 敏儿 : 28 , 月儿 : 25 , 花儿 : 21 , S小糖 : 49 , 悦悦 : 19 , 小可爱 : 29 , 紫琪 : 49 , 糖心 : 26 , 棒棒糖 : 23 , 猪猪侠 : 18 , 喵喵 : 27 , 安琦 : 19 , 叶子 : 20 ]

any:

判断集合中有木有年龄等于18岁的,此时用any就非常方便,如下:

看一下它的定义:

count:统计函数

查找一个年龄小于25岁的妹子的个数,如下:

find:查找第一个符合条件的并返回第一个

查找第一个是广东的妹子并打印出来,做法如下:

groupby:分组

按不同的地区对妹子集合进行分组,如下:

{山东=[Girl(name=依儿, age=18, height=168, address=山东), Girl(name=一生有你, age=22, height=163, address=山东), Girl(name=花儿, age=21, height=183, address=山东), Girl(name=猪猪侠, age=18, height=173, address=山东)], 河南=[Girl(name=笑笑, age=19, height=175, address=河南), Girl(name=喵喵, age=27, height=164, address=河南)], 福建=[Girl(name=小百合, age=17, height=155, address=福建)], 广东=[Girl(name=michel, age=22, height=148, address=广东), Girl(name=玲儿, age=23, height=169, address=广东), Girl(name=乔乔, age=35, height=180, address=广东), Girl(name=小可爱, age=29, height=158, address=广东), Girl(name=叶子, age=20, height=160, address=广东)], 广西=[Girl(name=猫咪, age=28, height=159, address=广西), Girl(name=悦悦, age=19, height=160, address=广西)], 安微=[Girl(name=环环, age=25, height=172, address=安微)], 河北=[Girl(name=胖嘟嘟, age=32, height=180, address=河北), Girl(name=安琦, age=19, height=159, address=河北)], 江西=[Girl(name=小可爱, age=27, height=150, address=江西)], 黑龙江=[Girl(name=敏儿, age=28, height=155, address=黑龙江)], 吉林=[Girl(name=月儿, age=25, height=178, address=吉林)], 新疆=[Girl(name=S小糖, age=49, height=190, address=新疆), Girl(name=紫琪, age=49, height=149, address=新疆)], 甘肃=[Girl(name=糖心, age=26, height=165, address=甘肃)], 浙江=[Girl(name=棒棒糖, age=23, height=172, address=浙江)]}

接着打印出广东组的所有妹子,可以这样做:

因为有可能组里没有广东的,也就是数据源可能为null,所以要想让上面的错误解除,则需要加入它:

自定义dsl入门:

什么是dsl呢?领域专用语言(domain specific language / DSL),也就是可以用自然语言来执行程序,让没有任何编程背景的人也能参考到编程当中来,第五代自然编程语言也是未来编程发展一个趋势,所以kotlin未来可期,学习它需要以下两个基础,之前已经学习过了:

  • 扩展函数
  • 中缀表达式

还是以查找妹子为例,先定义一个扩展函数,如下:

调用一下:

下面继续用中缀表达式对其进一步封装,使其更加简单,如下:

此时的调用就可以变为以空格分隔,如下:

接着再来定义大于指令年龄的,如下:

这就是DSL领域专用语言,下面再来定义一个:

那有了DSL之后,可以将程序包装成一个0难度上手的接口,但是实际中怎么用,这个待未来挖掘。

posted on 2018-02-08 11:20  cexo  阅读(461)  评论(0编辑  收藏  举报

导航