Kotlin从入门进阶到实战
Kotlin是在java类库基础上进行了改造和扩展,引入了不可变集合类,同时扩展了大量方便实用的功能,这些功能api都在kotlin.collections包下。
在kotlin集合类中不仅能支持普通对象,而且能够持有函数类型的变量。
val funList: List<(Int) -> Boolean> = listOf({ it -> it % 2 == 0 }, { it -> it % 2 == 1 })
fun test() {
val list = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9)
val result = list.filter(funList[0])
val result1 = list.filter(funList[1])
println(result)
println(result1)
}
这就是面向对象式和函数式编程混合开发的样子
Kotlin中分别用 listOf()、setOf()、mapOf() 创建不可变的容器,使用mutableListOf() 、mutableSetOf() 、mutableMapOf() 创建可变的Mutable容器
代码示例如下
val list = listOf(1, 2, 3, 4, 5)//创建不可变List
val mutableList = mutableListOf(1, 2, 3, 4, 5)//创建可变mutableList
val set = setOf(1,2,3,4,5)//创建不可变Set
val mutableSet = mutableSetOf(1,2,3,4,5)//创建可变mutableSet
val map = mapOf(1 to "A" , 2 to "B" ,3 to "C")//创建不可变Map
val mutableMap = mutableMapOf(1 to "A" , 2 to "B" ,3 to "C")//创建可变mutableMap
Type inference failed: Not enough information to infer parameter T in inline fun listOf( ): List Please specify it explicitly.
val list = listOf()
val set = setOf()
val map = mapOf()
val list = listOf(1, 2, 3, 4, 5, 6)
list.forEach { println(it) }
val set = setOf("A", "B", "C")
set.forEach { println(it) }
val map = mapOf(1 to "o", 2 to "p", 3 to "q")
map.forEach { println("key = ${it.key} value = ${it.value}") }
在Iterable和Map中,forEach函数都是一个内联inline函数。另外如果我们想在迭代器遍历的时候获取index下标,在List和Set中可以使用下面的forEachIndexed函数
val list = listOf(1, 2, 3, 4, 5, 6)
//第一个参数是index 第二个参数 i 是value
list.forEachIndexed { index, i -> println("index = ${index} value = ${i}") }
val set = setOf("A", "B", "C")
set.forEachIndexed { index, s -> println("index = ${index} value = ${s}") }
Map的元素是Entry类型,有entries属性持有
public val entries: Set>
这个Entry类型定义如下
public interface Entry {
/**
* Returns the key of this key/value pair.
*/
public val key: K
/**
* Returns the value of this key/value pair.
*/
public val value: V
}
可以通过Entry属性获取Map所有键值对的Set
val map = mapOf(1 to "o", 2 to "p", 3 to "q")
map.entries.forEach { println("key = ${it.key} , value = ${it.value}") }
key = 1 , value = o
key = 2 , value = p
key = 3 , value = q
val list = listOf(1, 2, 3, 4, 5, 6)
val mapForList = list.map { it * it }// map函数对每个元素进行乘方操作
println(mapForList)
//输出结果如下
[1, 4, 9, 16, 25, 36]
val set = setOf("A", "B", "C")
val mapForSet = set.map { it + "helloMap" }//map函数对每个元素进行字符串拼接
println(mapForSet)
//输出结果如下
[AhelloMap, BhelloMap, ChelloMap]
val map = mapOf(1 to "o", 2 to "p", 3 to "q")
val mapForMap = map.map { it.value + "Map" }
println(mapForMap)
//输出结果如下
[oMap, pMap, qMap]
map函数如下:
public inline fun Iterable.map(transform: (T) -> R): List {
return mapTo(ArrayList(collectionSizeOrDefault(10)), transform)
}
这里的R类型是映射之后的数据类型,我们也可以传入一个List
val list = listOf(1, 2, 3, 4, 5, 6)
val mapFList = list.map { it -> listOf(it + 100, it + 1000, it + 10000) }
println(mapFList)
输出结果如下,每个元素映射为一个List,这个List中有三个元素 分别为 it + 100 it+1000 it+10000 ,这个时候返回值会是List套一个List
[[101, 1001, 10001], [102, 1002, 10002], [103, 1003, 10003], [104, 1004, 10004], [105, 1005, 10005], [106, 1006, 10006]]
Kotlin中还提供了一个flattern函数,效果是使结构变为一层还是上边的代码
val list = listOf(1, 2, 3, 4, 5, 6)
val mapFList = list.map { it -> listOf(it + 100, it + 1000, it + 10000) }.flatten()
println(mapFList)
输出如下
[101, 1001, 10001, 102, 1002, 10002, 103, 1003, 10003, 104, 1004, 10004, 105, 1005, 10005, 106, 1006, 10006]
flatMap函数是map和flat两个函数的复合逻辑,代码如下
val list = listOf(1, 2, 3, 4, 5, 6)
val mapFList = list.flatMap { it -> listOf(it + 1, it + 2) }
println(mapFList)
输出结果如下
[2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
data class Student(var name: String, var age: Int, var score: Int) {
override fun toString(): String {
return "$name ${age}岁 ${score}分"
}
}
@JvmStatic
fun main(args: Array) {
val list = listOf(Student("张三", 18, 80)
, Student("小明", 16, 70)
, Student("小李", 16, 50)
, Student("小王", 20, 100)
, Student("小陆", 18, 59))
val filter = list.filter { it.score < 60 }
println(filter)
}
如果想找到成绩不及格的学生。使用 list.filter { it.score < 60 }
[小李 16岁 50分, 小陆 18岁 59分]
如果查看年龄>= 18岁的
val filter = list.filter { it.age >= 18 }
//输出结果如下
//[张三 18岁 80分, 小王 20岁 100分, 小陆 18岁 59分]
val filter = list.filterIndexed { index, student -> index % 2 == 0 && student.score > 55}
//输出 [张三 18岁 80分, 小陆 18岁 59分]
val filter = list.filterIndexed { index, student -> index % 2 == 0 && index > 3 }
//输出 [小陆 18岁 59分]
filterIndexed()函数如下
public inline fun Iterable.filterIndexed(predicate: (index: Int, T) -> Boolean): List {
return filterIndexedTo(ArrayList(), predicate)
}
@JvmStatic
fun main(args: Array) {
val list = listOf(1, 2, 3)
val set = setOf(4, 5, 6)
println(list.reversed())
println(set.reversed())
}
打印输出如下
[3, 2, 1]
[6, 5, 4]
这个Iterable的扩展函数reversed()是直接调用的java.util.Collections.reverse()
public fun Iterable.reversed(): List {
if (this is Collection && size <= 1) return toList()
val list = toMutableList()
list.reverse()//调用java中List类型的reverse()方法
return list
}
@JvmStatic
fun main(args: Array) {
val list = mutableListOf(3, 2, 1)
val set = setOf(6, 5, 4)
println(list.sorted())
println(set.sorted())
}
输出如下
[1, 2, 3]
[4, 5, 6]
sorted()也是直接调用了java api来实现的
public fun > Iterable.sorted(): List {
if (this is Collection) {
if (size <= 1) return this.toList()
@Suppress("UNCHECKED_CAST")
return (toTypedArray>() as Array).apply { sort() }.asList()
}
return toMutableList().apply { sort() }
}
最终调用java.util.Arrays.sort()
public actual fun > MutableList.sort(): Unit {
if (size > 1) java.util.Collections.sort(this)
}
@JvmStatic
fun main(args: Array) {
val list = listOf(1, 2, 3, 4, 2, 5, 6, 4, 3, 5, 3, 1, 9)
println(list.distinct())
}
打印输出
[1, 2, 3, 4, 5, 6, 9]
data class Student(var name: String, var age: Int, var score: Int) {
override fun toString(): String {
return "$name ${age}岁 ${score}分"
}
}
@JvmStatic
fun main(args: Array) {
val list = listOf(Student("张", 10, 100)
, Student("张", 10, 100)
, Student("李", 20, 90))
println(list.distinct())
}
输出结果如下
[张 10岁 100分, 李 20岁 90分]