集合类是一种数据结构。
Kotlin中的集合类分为可变集合类和不可变集合类,主要类型为:list,set,map
List继承与Collection接口,主要特征是以线性存储,没有特定顺序,集合中可以存放重复对象。
Kotlin中的List分为不可变集合类List(ReadOnly) 和可变集合类MutableList(W&R)
不可变List不提供set、add等对list内容进行操作的方法,如果调用list.set方法,编译器会直接报错。
我们可以通过list.of方法来创建一个不可变List,如果创建的是一个空list,则必须声明变量的类型。
list根据索引取值,在java中我们使用list.get(index)方法,在Kotlin中,我们可以使用同样的方法,不过编译器会建议使用更简洁的方法,类似于数组的取值list[index]来取对应值。
fun testList(){
//创建一个空的list
val list1:List<String> = listOf()
Log.d(TAG,"list1.size:${list1.size}")
Log.d(TAG,"list1.class:${list1::class.java}")
val list2 = listOf("1")//一个元素 list2 List
Log.d(TAG,"list2.size:${list2.size}")
Log.d(TAG,"list2.class:${list2::class.java}")
val list3 = listOf("K","O","T","L","I","N",1,2,3)//多个元素 list3 List
Log.d(TAG,"list3.size:${list3.size}")
Log.d(TAG,"list3.class:${list3::class.java}")
Log.d(TAG,"list3[1]$list3[1]")
Log.d(TAG,"list3[1]${list3.get(1)}")
println(list3)
//D/CollectionTest: list1.size:0
//D/CollectionTest: list1.class:class kotlin.collections.EmptyList
//D/CollectionTest: list2.size:1
//D/CollectionTest: list2.class:class java.util.Collections$SingletonList
//D/CollectionTest: list3.size:9
//D/CollectionTest: list3.class:class java.util.Arrays$ArrayList
//I/System.out: [K, O, T, L, I, N, 1, 2, 3]
//D/CollectionTest: list3[1]O
//D/CollectionTest: list3[1]O
}
在MutableList中,除了List的基本函数外,添加了add,remove,set,clear,retaionAll等等修改List的操作函数。
我们可以通过mutableListOf方法来创建一个可变的list。
val mList1 = mutableListOf("1","2","Kotlin")//声明一个可变的集合
mList1.clear()
Log.d(TAG,"mList1$mList1")
val mList2 = mutableListOf("1","2","Kotlin","23","456","2")
Log.d(TAG,"mList2$mList2")
val result = mList2.retainAll(mutableListOf("1","Kotlin","retain"))//取两个集合的交集,并赋给mList2
Log.d(TAG,"result$result")
Log.d(TAG,"mList2$mList2")
//D/CollectionTest: mList1[]
//D/CollectionTest: mList2[1, 2, Kotlin, 23, 456, 2]
//D/CollectionTest: resulttrue
//D/CollectionTest: mList2[1, Kotlin]
同时我们可以将一个不可变的集合转换成一个可变集合
val list = listOf("pig","panda","dog")
val mlist3 = list.toMutableList()
mlist3[2] = "monkey"
mlist3.add("chicken")
Log.d(TAG,"mlist3:$mlist3")
//D/CollectionTest: mlist3:[pig, panda, monkey, chicken]
可以使用Iterator迭代器来遍历集合,也可以用forEach来遍历集合,当然,我们也可以用for循环
val list = mutableListOf("k", "a", "b", "d")
val iterator = list.iterator()
while (iterator.hasNext()) {
Log.d(TAG, "list:${iterator.next()}")
}
//D/CollectionTest: list:k
//D/CollectionTest: list:a
//D/CollectionTest: list:b
//D/CollectionTest: list:d
val list2 = mutableListOf<Char>()
for (a in 'a'..'z') {
list2.add(a)
}
Log.d(TAG, "list2:$list2")
//D/CollectionTest: list2:[a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z]
var str1 =""
list2.forEach { str1+="$it." }
Log.d(TAG,"list2:$str1")
//D/CollectionTest: list2:a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.
var str2 = ""
for (i in 0 until list2.size) {
str2+="${list2[i]}."
}
Log.d(TAG,"list2:$str2")
//D/CollectionTest: list2:a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.`
在Kotlin中我们可以用repeat来代替简单的for循环
var str3 = ""
repeat(list2.size){
i->
str3+="${list2[i]}."
}
Log.d(TAG,"list2 repeat:$str3")
// list2 repeat:a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.
常见的操作函数如下
函数 | 功能 |
---|---|
add、remove | 添加、删除元素 |
retainAll | 取两个集合交集(赋值给调用函数) |
contains | 是否包含某个元素 |
elementAt | 取对应值 |
first() last() | 返回集合第一个或者最后一个元素,空集则抛出异常 |
first(predicate:(T)->Boolean):T | 返回满足条件的第一个值,否则抛出异常 |
last(predicate:(T)->Boolean):T | 返回满足条件的最后一个值,否则抛出异常 |
indexOf(element:T) | 返回元素下标,没有则返回-1 |
indexOfLast(predicate:(T)->Boolean) | 返回满足条件的第一个下标,否则返回-1 |
indexOfLast(predicate:(T)->Boolean) | 返回满足条件的最后一个下标,否则返回-1 |
lastIndexOf(element) | 返回符合条件的最后一个元素的下标,否则返回-1 |
single | 如果该集合只有一个元素则返回该元素,否则抛出异常 |
single(predicate:(T)->Boolean) | 返回符合条件的单个元素,没有或者有多个元素则抛出异常 |
val list = mutableListOf("k", "a", "b", "d")
list.add("2")
Log.d(TAG, "list$list")//list[k, a, b, d, 2]
list.add(2, "4")//在对应位置添加元素
Log.d(TAG, "list$list")//list[k, a, 4, b, d, 2]
list.addAll(0, mutableListOf("3", "4", "5"))//添加一个集合中的元素
Log.d(TAG, "list$list")//list[3, 4, 5, k, a, 4, b, d, 2]
list.removeAt(0)//删除对应位置元素
list.remove("a")//删除元素
list.removeAll(mutableListOf("3", "4", "5"))
list.removeAll { it == "a" }//删除满足条件的元素
list.set(2, "替换值")
list[2] = "替换值"//和上面等价
list.clear()//清空集合
list.toList()//转换为不可变集合
list.retainAll(mutableListOf("2"))//取两个集合的交集
list.contains("o")//判断是否包含此元素
list.elementAt(3)//取对应index的元素,越界抛出异常
//我们可以使用以下方式处理越界的情况
val index9 = list.elementAtOrElse(9) { "123" }
Log.d(TAG, "index9$index9")//D/CollectionTest: index9123
list.elementAtOrNull(9)//越界返回null
list.first { it == "6" }//取第一个6
list.last { it == "6" }//取最后一个9
list.first()//取第一个值
list.last()//取最后一个值
list.indexOf("opppp")//list.indexOf("opppp")-1
list.indexOfFirst { it == "b" }//第一个b
list.indexOfLast { it == "b" }//最后一个b
list.lastIndexOf("1")//最后一个1
函数 | 功能 |
---|---|
any | 判断集合至少有一个元素 |
any(predicate: (T) -> Boolean) | 判断是否有满足条件的元素 |
all(predicate: (T) -> Boolean) | 是否都满足条件 |
none | 集合为空 |
none(predicate: (T) -> Boolean) | 集合中所有元素都不满足条件 |
count | 计算集合中元素的个数 |
reduce | 从第一项到最后一项进行累计运算(加减乘除等等) |
reduceRight | 从最后一项到第一项进行累计运算 |
fold(initial:R,operation:(acc:R,T)->R):R | 带初始值的reduce |
forEach | forEach遍历 |
forEachIndexed | 带index的遍历 |
max min | 最大值和最小值 |
maxBy(selector: (T) -> R): T? | |
minBy(selector: (T) -> R): T? | |
sumBy(selector: (T) -> Int): Int | 获取函数映射值的总和 |
val list = mutableListOf("1", "2", "a", "a", "b", "b")
Log.d(TAG, "list.any:${list.any()}")//集合不为空 list.any:true
Log.d(TAG, "list.any:${list.any { it != "1" }}")//集合包含不等于1 的值 list.any:true
Log.d(TAG, "list.none:${list.none { it == "5" }}")//集合不包含“5” list.none true
Log.d(TAG, "list is empty:${list.none()}")//集合为空 false
Log.d(TAG, "count ${list.count()}")//count 6
Log.d(TAG, "count ${list.count { it.toCharArray()[0] in 'a'..'z' }}") //count 4
Log.d(TAG, "reduce: ${list.reduce { result, b -> result + b }}")//reduce: 12aabb
Log.d(TAG, "reduce reduceRight: ${list.reduceRight { result, b -> b + result }}")//这里要注意的是reduceRight的运算是b+result,reduce reduceRight: bbaa21
Log.d(TAG, "fold:${list.fold("default") { result, b -> result + b }}")//defaultbbaa21
//foldRight 与reduceRight相同,计算为b+result
Log.d(TAG, "fold:${list.foldRight("default") { result, b -> b + result }}")//defaultbbaa21
list.forEachIndexed { index, s ->
if (s == "b")
Log.d(TAG, "b 的index:$index") // b的index:4 b的index:5
else
Log.d(TAG, "其他的index:$index")
}
//maxBy的参数是一个函数fun(x) 以集合的元素x作为参数,以此函数fun的返回值 R来比较大小,
// 返回满足条件的集合的元素x,注意这里并不是返回了参数函数fun的返回值R.minBy 同理
val list2 = mutableListOf(1, 2, 3, 4, 5, 6)
val result = list2.maxBy { 1 - it }
Log.d(TAG, "maxBy:$result")// maxBy:1
Log.d(TAG,"sumBy:${list2.sumBy { it+100 }}" )//sumBy:621
//注意sumBy 是获取函数返回值的总和,返回的是Int类型。函数的参数也是Int类型
函数 | 功能 |
---|---|
take | 挑出前n个集合元素组成子集合 |
takeWhile(predicate: (T) -> Boolean): List | 挑出满足条件的子集合 |
takeLast(n: Int): List | 取后n个元素的子集合 |
takeLastWhile(predicate: (T) -> Boolean): List | 从后取满足条件的子集合 |
drop(n: Int): List | 去除前N个元素 |
dropWhile(predicate: (T) -> Boolean): List | 去除满足条件的元素 |
dropLast(n: Int): List | 去除后n个元素 |
dropLastWhile(predicate: (T) -> Boolean): List | 从后去除满足条件的元素 |
slice(indices: Iterable): List | 返回一个区间的集合 |
slice(indices: IntRange): List | 返回制定下标的集合 |
filterTo(destination: C, predicate: (T) -> Boolean): C | 将满足条件的元素赋值给新的集合dest |
filter(predicate: (T) -> Boolean): List | 返回过滤出满足条件的元素集合 |
filterNot(predicate: (T) -> Boolean): List | 返回过滤出的不满足条件的集合 |
fifterNotNull | 过滤出非null元素 |
val list = mutableListOf(1, 2, 2, 3, 4, 5, 6)
val list6 = list.takeLastWhile { it > 4 }
Log.d(TAG, "list6:$list6")//list6:[5, 6]
val list2 = list.drop(2)
Log.d(TAG, "list2:$list2")//list2:[2, 3, 4, 5, 6]
val list3 = list.dropWhile { it > 3 }
Log.d(TAG, "list3:$list3")//list3:[1, 2, 2, 3, 4, 5, 6]
val list4 = list.dropLast(2)
Log.d(TAG, "list4:$list4")//list4:[1, 2, 2, 3, 4]
val list5 = list.dropLastWhile { it > 4 }
Log.d(TAG, "list5:$list5")//list5:[1, 2, 2, 3, 4]
val list7 = list.slice(2..5)
Log.d(TAG, "list7:$list7")//list7:[2, 3, 4, 5]
val list8 = mutableListOf<Int>()
list.filterTo(list8) { it > 2 }
Log.d(TAG,"list8:$list8" )//把满足条件的元素赋给list8 list8:[3, 4, 5, 6]
val list9 = list.filter { it>2 }
Log.d(TAG,"list9:$list9" )//list9:[3, 4, 5, 6]
需要注意的是,takeWhile、takeLastWhile、dropWhile、dropLastWhile等函数,在执行时如果遇到不满足条件的元素就会停止操作,所以上述例子里list3 的结果是list3:[1, 2, 2, 3, 4, 5, 6]
函数 | 功能 |
---|---|
map(transform: (T) -> R): List | 将经过转换函数操作的新元素存到一个新的集合中返回 |
mapIndexed(transform: (index: Int, T) -> R): List | 转换函数中带有index下标 |
map(transform: (T) -> R): List |
val list = mutableListOf(1, 2, 2, 3, 4, 5, 6)
val result1 = list.map { it * it }
Log.d(TAG, "result1$result1")//result1[1, 4, 4, 9, 16, 25, 36]
val result2 = list.mapIndexed { index, it -> (index * index) + it }
Log.d(TAG, "result2$result2")//result2[1, 3, 6, 12, 20, 30, 42]
val result3 = list.mapNotNull { if (it % 2 == 0) null else it*it }
Log.d(TAG, "result3$result3")//result3[1, 9, 25]
函数 | 功能 |
---|---|
groupBy(keySelector: (T) -> K): Map |
将集合中的元素按照条件选择器进行计算,并返回map。 |
groupingBy(crossinline keySelector: (T) -> K): Grouping |
创建一个grouping,并调用计数函数eachCount统计分组 |
函数 | 功能 |
---|---|
reversed() | 倒序排列集合元素 |
sorted | 升序排序 |
sortedDescending | 降序排序 |
sortedBy和sortedDescendingBy | 根据函数表达式进行升序或者降序 |
val list = mutableListOf(1, 2, 8, 3, 4, 5, 6)
val result1 = list.groupBy { it - 1 }
Log.d(TAG, "result1:$result1")//result1:{0=[1], 1=[2, 2], 2=[3], 3=[4], 4=[5], 5=[6]}
//groupBy(keySelector: (T) -> K): Map> 将集合中的元素按照条件选择器进行计算,并返回map。
Log.d(TAG, "list_sorted:${list.sorted()}")//list_sorted:[1, 2, 3, 4, 5, 6, 8]
Log.d(TAG, "list_sorted:${list.sortedDescending()}")//list_sorted:[8, 6, 5, 4, 3, 2, 1]
函数 | 功能 |
---|---|
zip(other: Iterable): List |
集合按照下标配对,组合成的pair为新的list集合中的元素,如果两个集合长度不一样,取较短的集合 |
partition(predicate: (T) -> Boolean): Pair |
根据条件将集合拆分成两个子集合组成的pair |
plus(elements: Iterable): List | 合并两个集合 |
Log.d(TAG, "zip:${list1.zip(list2)}")//zip:[(1, 7), (2, 8), (8, 9)]
Log.d(TAG,"partition:${list1.partition { it>3 }}" )//partition:([8, 4, 5, 6], [1, 2, 3])
Log.d(TAG,"partition:${list1.partition { it>10 }}" )//partition:([], [1, 2, 8, 3, 4, 5, 6])
Log.d(TAG,"plus:${list1.plus(list2)}" )//plus:[1, 2, 8, 3, 4, 5, 6, 7, 8, 9]
Log.d(TAG,"plusElement:${list1.plusElement(12)}" )//plusElement:[1, 2, 8, 3, 4, 5, 6, 12]
Log.d(TAG,"plusElement:$list1" )//plusElement:[1, 2, 8, 3, 4, 5, 6]
与list基本相似,在Kotlin中,Set也分为不可变Set和可变Set,MutableSet。
Set 中的元素是不可重复的。Kotlin中判断两个对象是否相等的标准是hashCode 和equals 两个参考值。
函数 | 功能 |
---|---|
setOf | 创建一个不可变的集合 |
mutableSetOf | 创建一个可变集合 |
emptySet | 创建一个空的set |
hashSetOf | 创建一个hashset |
linkedSetOf | 创建一个linkedHashset |
sortedSetOf | 创建一个创建一个集合并排序 |
TreeSetOf | 创建一个treeSet |
Kotlin 中的LinkedHashSet、HashSet、SortedSet、TreeSet 直接使用的就是java中的对应集合
加减操作:我们可以使用.plus 和.minus
方法来做一些加减操作比如:
val set1 = mutableSetOf(1,2,3,4,5)
Log.d(TAG,"set1.plus(6):${set1.plus(6)}" )//set1.plus(6):[1, 2, 3, 4, 5, 6]
Log.d(TAG,"set1.plus(6):${set1+7}" )//set1.plus(6):[1, 2, 3, 4, 5, 7]
Map 是一种按照键值对存储数据的集合,每个一个元素都由key和value组成。
从数据结构上看,list集合就是key为int类型的特殊map,set也是key为int,而且值不能重复的map。
函数 | 功能 |
---|---|
mapOf | 创建一个不可变的空map |
emptyMap |
创建一个空的map |
mutableMapOf() | 创建一个操作的Map |
hashMapOf | 创建一个HashMap |
linkedMapOf | 创建一个LinkedHashMap |
linkedMapOf(vararg pairs: Pair |
创建一个子元素为map的map |
sortedMapOf(vararg pairs: Pair |
创建一个根据key升序排序的map |
val map1 = emptyMap<String, Int>()
val map2 = map1.plus(pair = "a" to 1) + ("b" to 2)
Log.d(TAG, "map2:$map2")//map2:{a=1, b=2}
val map3 = linkedMapOf("a" to mutableMapOf("b" to 2), "b" to mutableMapOf("c" to 3))
Log.d(TAG, "map3:$map3")//map3:{a={b=2}, b={c=3}}
val map4 = sortedMapOf("c" to mutableMapOf("c" to 4),"a" to mutableMapOf("b" to 2), "b" to mutableMapOf("c" to 3))
Log.d(TAG, "map4:$map4")//map4:{a={b=2}, b={c=3}, c={c=4}}
Map元素包含的属性有:entries,keys,values,size,
属性 | 功能 |
---|---|
entries | map.entries 获取map中所有键值对的set |
keys | 获取所有的键的set |
values | 获取所有值的set |
size | 获取map的键值对个数 |
get(key) | 根据key获取value,可以使用操作符map[key],如果不包含key则返回null |
getOrDefault | 如果返回null时,返回默认值 |
函数 | 功能 |
---|---|
containsKey | 是否包含key |
containsValue | 是否包含value |
component1 component2 | 用来在entries中遍历时访问key和value |
Map.Entry.toPair | 将map的Entry的元素转换为Pair |
getOrElse | 通过key获取值,没有值则可以设置默认值 |
getValue(key) | 通过key获取值,如果不存在key,则抛出异常 |
getOrPut() | 如果没有key,则将此key存放入map,值为defaultvalue |
iterator() | 返回map的Iterator,可以用来遍历map |
filter(predicate: (Map.Entry |
返回满足entry条件的键值对组成的新的map |
filterKeys(predicate: (K) -> Boolean): Map |
返回key满足条件的键值对组成的新map |
filterValues(predicate: (V) -> Boolean): Map |
返回value满足条件的的键值对组成的新map |
val map1 = emptyMap<String, Int>()
val map2 = map1.plus(pair = "a" to 1) + ("b" to 2)
Log.d(TAG, "map2:$map2")//map2:{a=1, b=2}
val map3 = linkedMapOf("a" to mutableMapOf("b" to 2), "b" to mutableMapOf("c" to 3))
Log.d(TAG, "map3:$map3")//map3:{a={b=2}, b={c=3}}
val map4 = sortedMapOf("c" to mutableMapOf("c" to 4),"a" to mutableMapOf("b" to 2), "b" to mutableMapOf("c" to 3))
Log.d(TAG, "map4:$map4")//map4:{a={b=2}, b={c=3}, c={c=4}}
// map3.getValue("c")//Key c is missing in the map.
Log.d(TAG,"get:${map3["d"]}" )//get:null
map3.getOrPut("d") {mutableMapOf("c" to 4)}
Log.d(TAG,"get:${map3["d"]}" )//get:{c=4}
val map5 = mutableMapOf("a" to 1,"b" to 2, "c" to 3,"d" to 4)
Log.d(TAG,"map5.filter:${map5.filter { it.value >= 3 }}" )//map5.filter:{c=3, d=4}
Log.d(TAG,"map5.filterValues { it >3 }${map5.filterValues { it >3 }}" )//map5.filterValues { it >3 }{d=4}