Kotlin内联函数、高阶API学习
Kotlin 再次学习1
内联函数
内联函数大概有几个
- also
- apply
- run
- let
- with
- also、apply是返回对象本身
- run,let,with是返回函数闭包中最后执行的值
with
使用with的最大作用就是能够默认使用this来进行指代,让代码的可读性可能会更好
val dialog=with(AlertDialog.Builder(this)) {
// this:AlertDialog.Builder
this.setTitle("hello")
this.setIcon(R.drawable.ic_launcher_background)
this.setMessage("message")
this.create()
}
//此时,dialog为AlertDialog对象
也就是with中的对象是什么,那么this也指代什么。一般可以在初始化的时候进行使用。
inline fun <T, R> with(receiver: T, block: T.() -> R): R
apply
apply为一个扩展方法,就是在原有的基础上,进行内部变量的一些设定。可以和with相互转换,上述的例子转换成为apply后变成如下的代码。
val dialog=AlertDialog.Builder(this).apply {
// this:AlertDialog.Builder
this.setTitle("hello")
this.setIcon(R.drawable.ic_launcher_background)
this.setMessage("message")
//如果要返回,写在此处的返回为AlertDialog.Builder对象
}.create()
//此时dialog是AlertDialog对象
run
run方法也是一个扩展方法。比如一个对象使用了run方法后,就会依次执行run方法中的方法,然后返回最后执行的方法的返回值
val dialog=AlertDialog.Builder(this).run {
// this:AlertDialog.Builder
this.setTitle("hello")
this.setIcon(R.drawable.ic_launcher_background)
this.setMessage("message")
this.create()
}
// 此处dialog是AlertDialog对象
also
also,可以理解为是let和apply函数的加强版。和apply一致,返回值是该函数的接收者。
val dialog=AlertDialog.Builder(this).also {
// it:AlertDialog.Builder
it.setTitle("hello")
it.setIcon(R.drawable.ic_launcher_background)
it.setMessage("message")
}.create()
//此时,dialog对象为AlertDialog对象
let
let可以用来判空,与apply不同的是返回值。let返回的是闭包里面的值,apply返回的是原来的对象。
val dialog=AlertDialog.Builder(this).let {
// it:AlertDialog.Builder
it.setTitle("hello")
it.setIcon(R.drawable.ic_launcher_background)
it.setMessage("message")
it.create()
}
//此时,dialog返回的是AlertDialog对象
集合的高阶函数API
高阶函数大概可以有
- takeIf
- takeUnless
------这是分界线------
- map
------这是分界线------
- filter
- filterNot
- filterNotNull
------这是分界线------
- count
------这是分界线------
- sum
------这是分界线------
- fold
- reduce
------这是分界线------
- groupBy
------这是分界线------
- flatMap
- flatten
takeIf
引入想要判断一些特殊的东西,然后可以使用该返回类型进行let。当接收到某些满足的条件的时候,takeIf后的东西才会继续执行。
val correctResult=a.takeIf{it>10}.let{it+10}
//此时判断a是否大于10,如果大于10,那么加上10
takeUnless
与takeIf相反,当条件结果不满足的时候,也就是takeUnless中为false是,才会执行后面的东西。
val correctResult=a.takeUnless{it>10}.let{it+10}
//此时判断a是否大于10,如果小于10,那么加上10
map
map方法接收到了一个函数,这个函数对集合中的每一个元素进行操作,然后将操作进行结果返回,最后产生了一个由这些结果组成的集合。
val list= arrayOf(1,2,3,4,5,6,7,8,9)
val newList=list.map { it*10 }
此时在newList中,存在着list中的所有元素乘以10后的元素。
使用map的话,可以免去了for语句,同时也可以避免中间变量的定义。
filter
对于这个函数,可以用来筛选一些东西。对于满足条件filter{条件}的内容,就会进行塞选,从而保留下来,组成一个新的集合。
val list= arrayOf(1,2,3,4,5,6,7,8,9)
val newList=list.filter {it>5}
此时,newList中会存在大于5的集合,也就是newList=[6 7 8 9]
filterNot
这个与filter的作用相反,如果使用该内联函数,那么将会过滤掉与条件值不同的东西。
val list= arrayOf(1,2,3,4,5,6,7,8,9)
val newList=list.filter {it>5}
此时,newList中会存在小于等于5的集合,也就是newList=[1 2 3 4 5]
filterNotNull
这个是用来过滤掉值为null元素
count
用来统计符合条件的个数
val list= arrayOf(1,2,3,4,4,4,5,6,7)
val listCount=list.count {it==4}
在list集合中,统计值等于4的集合个数有多少个
sum
该方法用来进行求和,之前还有sumBy方法,但是该方法已经被废除。
val list= arrayOf(1,2,3,4,4,4,5,6,7)
val listSum=list.sum()
此时listSum=36
fold
fold需要接入的参数有两个,第一个一般为initial,也就是初始值。第二个参数为一个函数,该函数为当前便利到的集合元素。每一次都掉用这个函数,然后将产生的结果作为参数提供给下一次的掉用
第二个函数为operation: (acc: R, T) -> R
,此时,第一个参数为每次执行该函数后的返回结果,第二个参数为其他元素。
使用fold内联函数的时候,能够体现到了递归的思想。
val list= arrayOf(1,2,3,4,4,4,5,6,7)
val listSum=list.fold(0){ result,pos-> result+pos }
上述代码为求list中每个元素的总和,设定了初始值为0。如果list中没有元素,那么直接返回初始值,也就是0这个结果
reduce
reduce函数只是需要传入一个函数,函数的实现形式也与fold类似。只不过reduce无需传入初始值。
val list= arrayOf(1,2,3,4,4,4,5,6,7)
val listSum=list.reduce{ result,pos-> result+pos }
该例子也是求和。但是当list中没有元素的时候,使用reduce会进行异常的抛出。
groupBy
这个内联函数为分类函数。例如一个对象中如果按照部分属性进行划分的话,可能会划分出许多不同的集合。而groupBy这个函数就是使用来划分不同的集合的。据一个简单的例子
val list= arrayOf(1,2,3,4,4,4,5,6,7)
val listGroup=list.groupBy{ it }
list为一个基本的数据集合,其中仅是含有基本的数据类型。当我需要进行划分的时候,listGroup将会变成{1=[1], 2=[2], 3=[3], 4=[4, 4, 4], 5=[5], 6=[6], 7=[7]}
。此时可以知道该列表中的具体的分类了。
flatMap
如果得到一个嵌套的集合,并且需要对这个集合进行加工,使其成为一个扁平化的集合,然后再进行加工,得到一个仅仅是单列属性组成的集合(对应着一个data class、class而言)。此时使用内联函数flatMap可能会比较方便。
val arraylist=listOf(
listOf(Student("name1","sex1"),Student("name2","sex1"),Student("name3","sex2")),
listOf(Student("name4","sex1"),Student("name5","sex2")),
listOf(Student("name6","sex1"))
)
此时,经过处理后,如果仅仅是需要姓名一列,那么可以使用flatMap,例子如下
val arrayname=arraylist.flatMap{it.name}
此时arrayname的值便成为了
arrayname=["name1","name2","name3","name4","name5","name6"]
flatten
对于一个嵌套集合,如果想要经过处理,变成一个纯粹是一维的一个集合,可以使用这个内联函数,从而进行快速的转换。
也是上面的例子,如果需要得到一个数组中都是Student这个对象的集合,那么使用该函数即可
val array=arraylist.flatten()
此时,array就成为了
array=[Student("name1","sex1"),Student("name2","sex1"),Student("name3","sex2"),Student("name4","sex1"),Student("name5","sex2"),Student("name6","sex1")]