集合
list集合
list集合分为可变集合与不可变集合。由list of创建的集合为不可变集合,不能扩容,不能修改元素:
var list = listOf("张三","李四","王五")
//访问第二个元素
var get = list.get(1)
由mutableListOf创建的集合为可变集合。可以扩容,可以修改元素
var list = mutableListOf(1,2,3,4)
//把第二个元素改为10
list.set(1,10)
list集合的遍历可以用for和foreach遍历:
fun main(args: Array) {
var list = mutableListOf(1, 2, 3, 4)
list.set(1, 10)
//for遍历
for (i in list) {
println(i)
}
//foreach遍历
list.forEach { println(it) }
}
set集合的方法同list集合,但是要注意set集合是去重的。
map集合
同样的,在map集合中,存在两种快速创建方法。mapof创建的集合为不可变集合,mutableMapOf创建的集合为可变集合。map集合同样可以用for和foreach遍历。
高阶函数和lambda表达式
高阶函数定义
Kotlin 函数都是头等的,这意味着它们可以存储在变量与数据结构中、作为参数传递给其他高阶函数以及从其他高阶函数返回。可以像操作任何其他非函数值一样操作函数。把函数作为参数或者返回值的函数就是高阶函数。
高阶函数调用
在之前的学习中,函数内的计算公式只能是一个。比如计算a+b和a-b,那么就需要新建两个函数。那么,如何才能只调用一个函数就能计算这两种算法呢?即:不知道具体是要求和还是求差,但只要传递一个和的运算规则就可以求和;传递一个求差的运算规则就可以求差:
fun main(args: Array) {
val a = 10
val b = 20
var sum = 0
var result = 0
sum = cacl(a, b, ::add)
result = cacl(a, b, ::sub)
}
fun cacl(m: Int, n: Int, block: (Int, Int) -> Int): Int {
return block(m, n)
}
fun add(m: Int, n: Int): Int {
return m + n
}
fun sub(m: Int, n: Int): Int {
return m - n
}
调用高阶函数,需要什么函数就传什么函数。
高阶函数调用Lambda表达式
上例中,如果我们只想调用一次add函数,那么就没必要专门定义一个add函数。那么我们可以通过调用Lambda表达式来实现我们的需求:
fun main(args: Array) {
val a = 10
val b = 20
var sum = 0
var result = 0
sum = cacl(a, b, {m,n->m+n})
result = cacl(a, b, {m,n->m-n})
}
fun cacl(m: Int, n: Int, block: (Int, Int) -> Int): Int {
return block(m, n)
}
Lambda表达式的简化
原则:
1.lambda表达式是最后一个参数,可以把()前移
2.如果()前移之后()里面没有参数,()也可以省略
sum = cacl(a, b, {m,n->m+n})可以简化为 sum = cacl(a, b){m,n->m+n}。
单独存在的Lambda表达式
Lambda表达式和高阶函数一般是成对出现的,但是lambda也可以独立存在。
无参的Lambda表达式:
//无参的lambda表达式
{
println("hello")
}()
//或:
{
println("hi")
}.invoke()
有参的Lambda表达式:
fun main(args: Array) {
//有参的lambda表达式
val s = {
a:Int,b:Int->a+b
}(10,20)
//或
val d = {
a:Int,b:Int->a+b
}.invoke(10,20)
}
Lambda表达式的返回值以及保存Lambda表达式
Lambda表达式返回值就是最后一行:
fun main(args: Array) {
val reuslt =
{
10
"张三"
println("hello")
}() //返回的是lambda表达式的返回值
}
可以定义一个变量像保存对象一样保存Lambda表达式:
fun main(args: Array) {
//通过变量保存lambda表达式
val block = {
}
//调用
block()
block.invoke()
}
Lambda表达式使用it
Lambda表达式若只有一个参数,则可以省略掉这个参数,用it来表示:
fun main(args: Array) {
var a = 0
var result = add(a) {
it + 10
}
println(result)//20
}
fun add(m: Int, block: (Int) -> Int): Int {
return block(m) + 10
}
集合中的函数
过滤
集合过滤主要用到filter及其相关的函数:
fun main(args: Array) {
val list = listOf("张三", "李四", "王五", "赵六", "张四", "李五", "李六")
val list2 = listOf("周芷若", "张无忌", "张五", "李善长", "林青霞", "李寻欢")
//找出第一个姓张的
var s = list.indexOfFirst { it.startsWith("张") }
println(s)
//把第一个集合中所有姓张的找出来
var listn = list.filter { it.startsWith("张") }
for (s in listn) {
println(s)
}
//把两个集合中所有姓张的找到并存放在同一个集合中
var list0 = mutableListOf()
list.filterTo(list0) {
it.startsWith("张")
}
list2.filterTo(list0) {
it.startsWith("张")
}
println(list0)
//把第一个集合中角标为偶数的元素找出来
var list3 = list.filterIndexed{ index, s -> index % 2 == 0 }
println(list3)
}
排序
集合的排序要注意sorted及其相关函数:
fun main(args: Array) {
val list = listOf("g", "u", "q", "n", "d", "z", "a")
//正序排序
var sorted = list.sorted()
println(sorted)
//倒序排序
var sortedDescending = list.sortedDescending()
println(sortedDescending)
//按字段排序
val personList = listOf(Person("林青霞", 80), Person("张曼玉", 30), Person("郑少秋", 70))
//按年龄排序
var agelist = personList.sortedBy { it.age }
println(agelist)
//按姓名排序
var namelist = personList.sortedBy { it.name }
println(namelist)
}
data class Person(val name: String, val age: Int)//data表示重写toString方法
分组
分组所用到的函数是 groupby()
fun main(args: Array) {
val list = listOf("张三", "李四", "王五", "赵六", "张四", "李五", "李六")
//张的一组 姓李的一组 其他一组
val map = list.groupBy {
val firstname = it.substring(0, 1)
when (firstname) {
"张" -> "张"
"李" -> "李"
else -> "其他"
}
}
println(map)
}
最值
最值函数包括max,min,maxby,minby。
fun main(args: Array) {
val list = listOf("z", "e", "t", "n")
//最大值
var max = list.max()
println(max)
//最小值
var min = list.min()
println(min)
val personList = listOf(Person("林青霞", 50), Person("张曼玉", 30), Person("郑少秋", 70))
//对象集合最大值->年龄
var maxBy = personList.maxBy { it.age }
println(maxBy)
var minBy = personList.minBy { it.age }
println(minBy)
}
去重
去重所用到的函数为distinct和distinctby:
fun main(args: Array) {
val list = listOf("张三", "李四", "王五", "赵六", "张三", "张四", "李六")
//把重复的元素去掉
var distinct = list.distinct()
println(distinct)
//把重复的姓张的去掉
var distinctBy = list.distinctBy {
val first = it.substring(0, 1)
if (first == "张") {
"张"
} else {
it
}
}
println(distinctBy)
}
拆分
集合拆分所用到的函数为partition:
fun main(args: Array) {
val list = listOf("张三", "李四", "王五", "赵六", "张四", "李五", "李六")
//姓张的一部分,另外的一部分
var partition = list.partition { it.substring(0, 1) == "张" }
println(partition)
}
重组
重组所用到的函数为map():
fun main(args: Array) {
val personList = listOf(Person("林青霞", 50), Person("张曼玉", 30), Person("郑少秋", 70))
//将Person里面每一个name获取
var map = personList.map { it.name }
println(map)
}
元素相加
元素相加所用到的函数为sumby(),sumbydouble():
fun main(args: Array) {
val personList = listOf(Person("林青霞", 50), Person("张曼玉", 30), Person("郑少秋", 70))
//求出所有人的年龄之和
var sumBy = personList.sumBy { it.age }
println(sumBy)
}
四大表达式
Apply
1.任意对象、任意类型都有apply扩展函数
2.apply函数参数是函数类型,带接受者的函数字面值
3.apply函数返回值是当前对象本身
fun main(args: Array) {
val list: MutableList? = mutableListOf("林青霞", "张曼玉", "关之琳")
list?.apply {
indexOf("朱茵")
add("林志玲")
}?.add(2, "赵丽颖")//由于返回值对象是本身,所以括号后面还可以点上集合的函数
}
Let
1.let函数给任意类型添加的扩展函数
2.let函数参数是函数类型。函数参数它的参数就是自己本身
3.函数参数返回值是任意类型
4.let函数返回值就是block函数的返回值
5.使用it代表当前对象,返回值是表达式最后一行
let和apply最大的区别:函数参数不同。apply属于定义在对象里面的函数,let是普通函数
fun main(args: Array) {
val list: MutableList? = mutableListOf("林青霞", "张曼玉", "关之琳")
//apply
list?.apply {
indexOf("朱茵")
add("林志玲")
}?.add(2, "赵丽颖")
//let
var let = list.let {
10
"sda"
it?.add("李四")
}
}
with
1.with函数是一个独立的函数 可以独立使用
2.with函数有两个参数 第一个可以传递任意类型 第二个参数:带接收者的函数字面值 接收者是第一个参数
3.with函数返回值就是第二个函数参数返回值
with相当于是apply和let的结合,使用this代表当前对象,返回值是最后一行
fun main(args: Array) {
val list: MutableList? = mutableListOf("林青霞", "张曼玉", "关之琳")
with(list!!) {
add("张三")
this
}.add("李四")//由于大括号中最后一行是this,表示返回值是它本身,所以可以继续点集合的函数
}
run
run函数类似于apply函数,区别是run函数的返回值是最后一行
fun main(args: Array) {
val list: MutableList? = mutableListOf("林青霞", "张曼玉", "关之琳")
list.run {
add("王五")
this
}.add("赵四")//由于大括号中最后一行是this,表示返回值是它本身,所以可以继续点集合的函数
}