Kotlin基础知识_02-Lambda编程

Kotlin基础知识_02-Lambda编程

1. 集合(list, set, map)的创建与遍历

1.1 创建list

kotlin 支持以下两种方式创建集合:

val list = ArrayList<String>()
list.add("Apple")
list.add("Banana")
list.add("Orange")
list.add("Pear")
list.add("Grape")

val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape")

上述创建的是不可变的集合,即创建好了之后,无法再向其添加元素:

val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape")
list.add("WaterMelon") // Error, 无法添加元素

可通过下面方式创建可变集合,可变集合在创建完毕之后,仍然能够向其添加元素

val list = mutableListOf("Apple", "Banana", "Orange", "Pear", "Grape")
list.add("Watermelon")

使用的是 mutableListOf() 函数。

1.2 创建set

创建set:

val set = setOf("Apple", "Banana", "Orange", "Pear", "Grape")
val set = mutableSetOf("Apple", "Banana", "Orange", "Pear", "Grape")

1.3 创建map

val map = HashMap<String, Int>()
map.put("Apple", 1)
map.put("Banana", 2)
map.put("Orange", 3)
map.put("Pear", 4)
map.put("Grape", 5)

val map = HashMap<String, Int>()
map["Apple"] = 1
map["Banana"] = 2
map["Orange"] = 3
map["Pear"] = 4
map["Grape"] = 5

Note:

  1. kotlin 不推荐使用 put()get()方法来对map进行添加和读取操作,而是更加推荐使用一种类似于数组下标的语法结构,比如向Map中添加一条数据就可以这么写:
map["Apple"] = 1

而从Map中读取一条数据就可以这么写:

val number = map["Apple"]

更简化的写法:

val map = mapOf("Apple" to 1, "Banana" to 2, "WaterMelon" to 3)

1.4 遍历list与set

遍历list

fun main() {
    val list = listOf("a", "b", "c", "d")
    for (i in list) {
        println("i = $i")
    }
}

输出:

i = a
i = b
i = c
i = d

遍历set

fun main() {
    val set = setOf("a", "b", "c", "d")
    for (i in set) {
        println("i = $i")
    }
}

输出:

i = a
i = b
i = c
i = d

1.5 遍历map

fun main() {
    val map = mapOf("a" to 1, "b" to 2, "c" to 3, "d" to 4, "e" to 5)
    for ((alphabet, num) in map) {
        println("alphabet = $alphabet, num = $num")
    }
}

输出:

alphabet = a, num = 1
alphabet = b, num = 2
alphabet = c, num = 3
alphabet = d, num = 4
alphabet = e, num = 5

Note: 这里是将Map的键值对变量一起声明到了一对括号里面,这样当进行循环遍历时,每次遍历的结果就会赋值给这两个键值对变量。

2. Lambda编程在集合API中的应用: maxBy(), map(), filter(), any(), all()

2.1 maxBy()

maxBy() 函数用于返回产生给定函数最大值的第一个元素。

ex:

fun main() {
    val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
    val value = list.maxBy { it.length }
    println("max length fruit is: $value")
}

输出:

max length fruit is: Watermelon

Note: 给定的匿名函数是一个Lambda表达式,它返回每个list集合中每个元素的length: it.length

See: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/

2.2 map()

map() 函数用于返回一个新的列表,该列表的元素包含将给定变换函数应用于原始数组中每个元素的结果。

ex:

fun main() {
    val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
    val newList = list.map { it.toUpperCase() }
    for (fruit in newList) {
        println("fruit is: $fruit")
    }
}

输出:

fruit is: APPLE
fruit is: BANANA
fruit is: ORANGE
fruit is: PEAR
fruit is: GRAPE
fruit is: WATERMELON

Note: 返回了一个新的列表,列表中的每一个元素都已经转换为了大写。

2.3 filter()

filter()函数用于返回仅包含与指定条件相匹配的元素的列表。

ex 过滤列表中长度大于5的元素:

fun main() {
    val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
    val newList = list.filter { it.length > 5 }
    for (fruit in newList) {
        println("fruit is: $fruit")
    }
}

输出:

fruit is: Banana
fruit is: Orange
fruit is: Watermelon

ex: 过滤列表中长度大于5的元素,并将其全部转换为小写:

fun main() {
    val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
    val newList = list.filter { it.length > 5 }
        .map { it.toLowerCase() }
    for (fruit in newList) {
        println("fruit is: $fruit")
    }
}

输出:

fruit is: banana
fruit is: orange
fruit is: watermelon

2.4 any()

any()函数,用于判断集合中是否至少存在一个元素能够满足指定条件,只要有一个元素能够满足条件,则返回true.

ex:判断列表中是否存在在单词长度大于5的元素:

fun main() {
    val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
    val result = list.any { it.length > 5 }
    println("result: $result")
}

输出;

result: true

2.5 all()

all()函数,用于判断集合中的元素是否均满足给定条件,如果全部都满足,则返回 true

ex: 判断集合中的元素长度是否均大于5

fun main() {
    val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
    val result = list.all { it.length > 5 }
    println("result: $result")
}

输出:

result: false

3. 简化匿名内部类中的单抽象方法接口的使用

kotlin中可使用上述函数式API的写法,即向函数参数中传入一小段代码块,当调用java中的代码时也可以这样写,不过仅限于java中的单抽象方法接口,所谓的单抽象方法接口,类似于下面的形式:

new Thread(new Runnable() {
	@Override
	public void run() {
		System.out.println("Thread is running");
	}
})

如上图code, 匿名内部类 new Runnable 有且仅有一个单抽象方法接口:run(), 当 kotlin 调用上述代码时,可将其简写成:

Thread {println("Thread is running")}

简化步骤:

  1. 原始的java code 用kotlin 可写成:
Thread(object: Runnable() {
    override fun run() {
        println("Thread is running")
    }
})

PS: \kotlin 没有 new关键字,所以创建匿名内部类就不能再写 new了,而且改用 object关键字。

  1. 该匿名内部类仅有一个单抽象方法接口 run(), 即使不写 override fun run(), 也知道代码块是在 run()方法中执行的, 符合上述约定,故可简写成:
Thread(Runnable() {
	println("Thread is running")
})
  1. 由于参数列表中有且仅有一个Java单抽象方法接口参数,再次简化:
Thread({
	println("Thread is running")
}).start()
  1. 当小括号中的Lambda表达式是方法的最后一个参数时,可以将Lambda表达式移到方法括号的外面。同时,如果Lambda表达式还是方法的唯一一个参数,还可以将方法的括号省略:
Thread {
	println("Thread is running")
}.start()

在 Android 中还有相似的应用,如给View 注册一个点击事件:

button.setOnClickListener(new View.OnClickListener() {
	@Override
	public void onClick(View v) {
		Log.e(TAG, "click the btn")
    }
});

用kotlin 可简化成:

button.setOnClickListener {
	Log.e(TAG, "click the btn")
}

当用kotlin 调用java 代码时,若java 代码是上述形式,均可使用kotlin的这种简化写法。



如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
posted @   夜行过客  阅读(52)  评论(0)    收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示