kotlin学习第五天:集合,高阶函数,Lambda表达式

集合

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,表示返回值是它本身,所以可以继续点集合的函数
}

你可能感兴趣的:(kotlin学习第五天:集合,高阶函数,Lambda表达式)