Kotlin复用了Java集合类,并且在Java类库的基础上进行了改造和扩展,没有重复造轮子。
Kotlin引入了不可变集合类,同时扩展了大量实用的功能,API在kotlin.collections
包下。
Kotlin集合类不仅可以持有普通对象,还能持有函数类型的对象 —— 面向对象范式混合了函数式编程。
// 例如:
fun testFunCollection(): Unit {
// 声明一个持有类型为函数 (Int)->Boolean 的集合
// (Int)->Boolean 代表输入为Int类型,输出为Boolean类型的函数
val funList:List<(Int)->Boolean> = listOf(
{it%3==1},{it%3==2},{it%3==0}
) // 第一个对象是函数 {it%3==1},第二个对象是函数 {it%3==2} ...
val myData = listOf(1,2,3,4,5,6,7,8,9)
val r0 = myData.filter(funList[0]) // 传入funList的第一个函数
println(r0) // 输出:[1, 4, 7]
val r1 = myData.filter(funList[1]) // 传入funList的第二个函数
println(r1) // 输出:[2, 5, 8]
val r2 = myData.filter(funList[2]) // 传入funList的第三个函数
println(r2) // 输出:[3, 6, 9]
}
Kotlin集合类分为:
列表(List)容器中的元素以线性方式存储,元素有序排列,集合中可以存放重复元素;
列表分为只读不可变的List和可写入、可删除数据的MutableList。
集(Set)容器中的元素无序、不重复;
集容器分为不可变Set和可变MutableSet(可写入、可删除数据)。
映射(Map)容器中持有的是“键值对”对象,关键字(Key)是唯一的、不重复的。
映射容器也一样,分为不可变Map和可变MutableMap(可写入、可删除数据);
Map没有继承自Collection接口。
listOf()
,setOf()
,mapOf()
函数创建不可变的列表(List)容器、集(Set)容器和映射(Map)容器;MutableListOf()
,MutableSetOf()
,MutableMapOf()
函数创建可变的MutableList列表容器、MutableSet集容器和MutableMap映射容器。fun testCollectionInit(): Unit {
val list = listOf(1,2,3,5,5,6,8,8,9)
println(list) // 输出:[1, 2, 3, 5, 5, 6, 8, 8, 9]
val mutableList = mutableListOf("a","b","c","a")
println(mutableList) // 输出:[a, b, c, a],列表中元素是可以重复的
val set = setOf(1,2,3,5,5,6,8,8,9)
println(set) // 输出:[1, 2, 3, 5, 6, 8, 9],结果去除重复
val mutableSet = mutableSetOf("a","b","c","a")
println(mutableSet) // 输出:[a, b, c],结果去除重复
val map = mapOf(1 to "a", 2 to "b", 3 to "a", 4 to 99, 1 to "xy")
println(map) // 输出:{1=xy, 2=b, 3=a, 4=99},key值唯一
val mutableMap = mutableMapOf(1 to "X", 2 to "Y", 3 to "Y", 4 to 99, 1 to "ABC")
println(mutableMap) // 输出:{1=ABC, 2=Y, 3=Y, 4=99},key值唯一
}
forEach() 函数
List、Set类 继承了 Iterable
接口,扩展了 forEach()
函数来遍历元素;
Map类也扩展了 forEach()
函数来遍历元素;
forEachIndexed() 函数
List、Set类中的 forEachIndexed()
函数,在遍历元素的时候访问元素的index下标.
Map中的 entries
属性
Map中的元素类型是 Entry
类型,由 entries
属性持有, entries
类型是Set
。
public val entries: Set<Map.Entry<K, V>>
代码示例:
fun testCollectionInit(): Unit {
val list = listOf(1,2,3,5,5,6,8,8,9)
println(list) // 输出:[1, 2, 3, 5, 5, 6, 8, 8, 9]
val mutableList = mutableListOf("a","b","c","a")
println(mutableList) // 输出:[a, b, c, a],列表中元素是可以重复的
list.forEach {
print(it)
print(" - ")
} // 输出:1 - 2 - 3 - 5 - 5 - 6 - 8 - 8 - 9 -
println()
list.forEachIndexed { index, value ->
print("index=$index,value=$value ")
} // 输出:index=0,value=1 index=1,value=2 index=2,value=3 .......
println("-------------------")
val set = setOf(1,2,3,5,5,6,8,8,9)
println(set) // 输出:[1, 2, 3, 5, 6, 8, 9],结果去除重复
val mutableSet = mutableSetOf("a","b","c","a")
println(mutableSet) // 输出:[a, b, c],结果去除重复
set.forEach {
print(it)
print(" - ")
} // 输出:1 - 2 - 3 - 5 - 6 - 8 - 9 -
println()
set.forEachIndexed { index, value ->
print("index=$index,value=$value ")
} // 输出:index=0,value=1 index=1,value=2 index=2,value=3 .......
println("-------------------")
val map = mapOf(1 to "a", 2 to "b", 3 to "a", 4 to 99, 1 to "xy")
println(map) // 输出:{1=xy, 2=b, 3=a, 4=99},key值唯一
val mutableMap = mutableMapOf(1 to "X", 2 to "Y", 3 to "Y", 4 to 99, 1 to "ABC")
println(mutableMap) // 输出:{1=ABC, 2=Y, 3=Y, 4=99},key值唯一
map.forEach {
print("key=${it.key},value=${it.value} ")
} // 输出:key=1,value=xy key=2,value=b key=3,value=a key=4,value=99
println()
val me = map.entries
println(me) // 输出:[1=xy, 2=b, 3=a, 4=99]
me.forEachIndexed { index, entry ->
print("index=$index,key=${entry.key},value=${entry.value} ")
} // 输出:index=0,key=1,value=xy index=1,key=2,value=b ......
}
集合类的map()
函数,可以将集合中的元素依次使用输入的函数进行映射操作,
元素映射之后的新值回保存到一个新的集合对象中,并且返回这个新集合对象。
fun testFunMap(): Unit {
val list = listOf(1,2,3,5,5,6,8,8,9)
val set = setOf(1,2,3,5,5,6,8,8,9)
val map = mapOf(1 to "a", 2 to "b", 3 to "xy")
val l2 = list.map { it*2 } // 函数对每个元素进行乘以2操作
println(list) // 输出:[1, 2, 3, 5, 5, 6, 8, 8, 9]
println(l2) // 输出:[2, 4, 6, 10, 10, 12, 16, 16, 18]
val s2 = set.map { it + 10 } // 函数对每个元素进行 加10操作
println(set) // 输出:[1, 2, 3, 5, 6, 8, 9]
println(s2) // 输出:[11, 12, 13, 15, 16, 18, 19]
val m2 = map.map { it.value + "_ok" }
println(map) // 输出:{1=a, 2=b, 3=xy}
println(m2) // 输出:[a_ok, b_ok, xy_ok]
}
public inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R> {
return mapTo(ArrayList<R>(collectionSizeOrDefault(10)), transform)
}
public inline fun <K, V, R> Map<out K, V>.map(transform: (Map.Entry<K, V>) -> R): List<R> {
return mapTo(ArrayList<R>(size), transform)
}
返回结果的数据类型是List
,返回结果是列表集合,该集合中的元素类型是R
.
R
既可以是普通数据类型,也可以是集合类型。
fun testListResult(): Unit {
val list = listOf(1,2,9)
// 函数对每个元素进行创建一个list集合操作,此集合的元素是原集合的元素分别加特定数字后的结果
val ll = list.map { listOf(it + 100, it+110, it+120, it+130) }
println(list) // 输出:[1, 2, 9]
println(ll) // 输出:[[101, 111, 121, 131], [102, 112, 122, 132], [109, 119, 129, 139]]
// 最终的输出结果ll 是一个List集合里嵌套List集合。
val fll = ll.flatten() // flatten() 函数用于将嵌套的集合"铺平"
println(fll) // 输出:[101, 111, 121, 131, 102, 112, 122, 132, 109, 119, 129, 139]
// flatMap() 函数是 map()和flatten() 两个函数的"复合逻辑"
val flm = list.flatMap { listOf(it *2, it*3, it*4, it*5) }
println(flm) // 输出:[2, 3, 4, 5, 4, 6, 8, 10, 18, 27, 36, 45]
}
fun testFilterF(): Unit {
val list = listOf(1,2,5,8,7,9)
val result = list.filter { it>5 } // 过滤出list中大于5的数
println(result) // 输出:[8, 7, 9]
}
class Person(var name: String, var age:Int, var sex:String) {
// override 关键字,重写 toString() 函数
override fun toString(): String {
return "Person【name: $name, age: $age, sex:$sex】"
}
}
fun testFilterF2(): Unit {
val list = listOf(
Person("Jack",18,"M"),
Person("Jhon",21,"M"),
Person("Lucy",19,"W"),
Person("Lily",20,"W"),
)
val result = list.filter { it.age>19 } // 过滤出年龄大于19的人
println(result) // 输出:[Person【name: Jhon, age: 21, sex:M】, Person【name: Lily, age: 20, sex:W】]
}
public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T> {
return filterTo(ArrayList<T>(), predicate)
}
public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterTo(destination: C, predicate: (T) -> Boolean): C {
for (element in this) if (predicate(element)) destination.add(element)
return destination
}
fun testFilterIndexedF(): Unit {
val list = listOf(1,2,5,8,7,9)
// 带下标过滤list元素
val result = list.filterIndexed { index, i -> index %2==1 && i < 7 }
println(result) // 输出:[2]
}
public inline fun <T> Iterable<T>.filterIndexed(predicate: (index: Int, T) -> Boolean): List<T> {
return filterIndexedTo(ArrayList<T>(), predicate)
}
public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterIndexedTo(destination: C, predicate: (index: Int, T) -> Boolean): C {
forEachIndexed { index, element ->
if (predicate(index, element)) destination.add(element)
}
return destination
}
fun testReversed(): Unit {
val list = listOf(1,2,5,18,27,9)
val result = list.reversed()
println(result) // 输出:[9, 27, 18, 5, 2, 1]
val set = setOf(1,2,3,25,15,6,8,28,9)
val r2 = set.reversed()
println(r2) // 输出:[9, 28, 8, 6, 15, 25, 3, 2, 1]
}
其实是将集合倒着排列,没有按大小排序。
public fun <T> Iterable<T>.reversed(): List<T> {
if (this is Collection && size <= 1) return toList()
val list = toMutableList()
list.reverse()
return list
}
public actual fun <T> MutableList<T>.reverse(): Unit {
java.util.Collections.reverse(this)
}
Kotlin的 reversed()
函数是直接调用 java.util.Collections.reverse()
方法。
val r3 = list.sorted()
println(r3) // 输出:[1, 2, 5, 9, 18, 27]
val r4 = set.sorted()
println(r4) // 输出:[1, 2, 3, 6, 8, 9, 15, 25, 28]
将集合中的元素,按照大小进行升序排列。
public fun <T : Comparable<T>> Iterable<T>.sorted(): List<T> {
if (this is Collection) {
if (size <= 1) return this.toList()
@Suppress("UNCHECKED_CAST")
return (toTypedArray<Comparable<T>>() as Array<T>).apply { sort() }.asList()
}
return toMutableList().apply { sort() }
}
public actual fun <T : Comparable<T>> MutableList<T>.sort(): Unit {
if (size > 1) java.util.Collections.sort(this)
}
Kotlin的 sorted()
函数是直接调用 java.util.Collections.sort()
方法。
fun testDistinct(): Unit {
val list = listOf(1,2,3,5,5,6,8,8,9)
println(list) // 输出:[1, 2, 3, 5, 5, 6, 8, 8, 9]
val result = list.distinct()
println(result) // 输出:[1, 2, 3, 5, 6, 8, 9]
}
public fun <T> Iterable<T>.distinct(): List<T> {
return this.toMutableSet().toList()
}
先将List集合转换成Set集合,以达到去除重复元素的目的,再将Set集合转换成List集合,作为结果返回。