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难度上手的接口,但是实际中怎么用,这个待未来挖掘。
kotlin高阶函数实战&DSL入门的更多相关文章
- Kotlin高阶函数实战
前言 1. 高阶函数有多重要? 高阶函数,在 Kotlin 里有着举足轻重的地位.它是 Kotlin 函数式编程的基石,它是各种框架的关键元素,比如:协程,Jetpack Compose,Gradle ...
- Kotlin高阶函数与函数式编程详解
函数可变参数: 在上一次https://www.cnblogs.com/webor2006/p/11518425.html中学到了可变参考,关于可变参数有如下规则说明: “一个方法中,只允许一个参数为 ...
- Kotlin——高级篇(二):高阶函数详解与标准的高阶函数使用
在上面一个章节中,详细的讲解了Kotlin中关于Lambda表达式的语法以及运用,如果还您对其还不甚理解,请参见Kotlin--高级篇(一):Lambda表达式详解.在这篇文章中,多次提到了Kotli ...
- Python入门篇-高阶函数
Python入门篇-高阶函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.高级函数 1>.First Class Object 函数在Python中是一等公民 函数也 ...
- Kotlin的高阶函数和常用高阶函数
Kotlin的高阶函数和常用高阶函数 文章来源:企鹅号 - Android先生 高阶函数的定义 将函数当做参数或者是返回值的函数 什么是高阶函数 可以看看我们常用的 函数: 首先我们可以知道, 是 的 ...
- 《React后台管理系统实战 :一》:目录结构、引入antd、引入路由、写login页面、使用antd的form登录组件、form前台验证、高阶函数/组件
实战 上接,笔记:https://blog.csdn.net/u010132177/article/details/104150177 https://gitee.com/pasaulis/react ...
- python入门16 递归函数 高阶函数
递归函数:函数内部调用自身.(要注意跳出条件,否则会死循环) 高阶函数:函数的参数包含函数 递归函数 #coding:utf-8 #/usr/bin/python """ ...
- 07.Javascript——入门高阶函数
高阶函数英文叫Higher-order function..JavaScript的函数其实都指向某个变量.既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数 ...
- kotlin之高阶函数
高阶函数是一种特殊的函数,它接受函数作为参数,或者返回一个函数 import java.awt.geom.Area fun main(arg: Array<String>) { val m ...
随机推荐
- Hibernate5 Guide
(1) 创建Maven工程 可以使用Eclipse或IDEA创建 (2) 修改pom文件 <project xmlns="http://maven.apache.org/POM/4.0 ...
- SQL- 将一张表的数据插入到另一张表,表结构不一致(加条件)
公司业务需要,在对表进行操作的时候将操作人和操作记录记录到日志表里.记录下来以供参考和学习. 首先准备两张测试表:Info以及InfoLog 1.表结构相同的情况下: insert into Info ...
- Django Model 基础数据库操作应用
https://blog.csdn.net/Mrzhangjwei/article/details/53001841 一.数据库操作1.创建model表 基本结构: from django.db im ...
- 大觅网03Day
实现轮播图接口 1.在开始工作之前请先准备好以下要用到的软件以及素材: MarkdownPad: POSTMAN: dm-common(install打包操作-保证本地构建), dm-base-pro ...
- LinuxC/C++基础——引用
1.引用(Reference) 1.1引用的基本语法 引用是C++对C的重要扩充,也存在与其他一些编程语言中,并不是C++的发明.通过引用,C++增加了 另外一种给函数传递地址的途径,这就是按引用传递 ...
- Kali Linux 2019.2安装谷歌输入法
前言 Linux下常用的中文输入法平台有IBus.fcitx和scim.scim现在维护滞后,不推荐使用. IBus ("Intelligent Input Bus") 是一个 输 ...
- 【Python开发】Python PIL ImageDraw 和ImageFont模块学习
ImageDraw 新建一个空白图片为本文作示例,新建空白文件的方法 见Image模块,Image.new: mport Image blank = Image.new("RGB&quo ...
- CentOS7修改内核启动顺序
CentOS7修改内核启动顺序: 1.首先查看当前系统有几个内核 cat /boot/grub2/grub.cfg |grep menuentry 2.查看当前默认内核 grub2-editenv ...
- C++调用windowsAPI实现目录zip压缩
TCHAR zipname[] = "C:\\bcel"; TCHAR zipfile [FILENAME_MAX]; sprintf(zipfile, "%s.zip& ...
- C++多线程基础学习笔记(七)
一.std::async和std::future的用法 std::async是一个函数模板,std::future是一个类模板 #include <iostream> #include & ...