Kotlin——集合
Kotlin集合概述
Kotlin的集合类由两个接口派生:Collection和Map。Collection和Map是Java集合框架的根接口,这两个接口又包含一些子接口或实现类
Java中的集合都是可变集合,但Kotlin的集合被分为两大类:可变集合和不可变集合。
- 可变集合:能添加、删除、修改元素
-
不可变集合:读取元素
collection集合体系的继承树
从这个图中可以看到Kotlin为Collection接口派生了一个子接口——MutableCollection,该子接口又包含了两个子接口:MutableSet和MutableList,这一分支就代表了Kotlin的可变集合。而Collection直接派生的Set和List接口则代表了不可变集合
Kotlin在JVM平台上并未真正实现HashSet、LinkedHashSet、LinkedHashSet、ArrayList这些类,只是为Java的HashSet、LinkedHashSet、ArrayList指定了一个类型别名。这样就直接借用了Java的这些集合类。
Kotlin也提供了Map集合。
Map集合体系的继承树
Kotlin的Map派生了MutableMap接口,代表了一个可变的Map集合。
Set集合
声明和创建Set集合
Kotlin并没有真正为JVM平台实现任何Set集合类通过别名借用了Java集合框架的类,不推荐使用构造器创建Set集合。推荐使用Kotlin提供的工具函数来创建Set集合
- setOf():返回不可变的Set集合
- mutableSetOf():返回可变的MutableSet集合
- hashSetOf():返回可变的HashSet集合
- linkedSetOf():返回可变的LinkedHashSet集合
- sortedSetOf():返回可变的TreeSet集合
对于Kotlin1.1 setOf() mutableSetOf()这两个函数实际返回的是LinkedHashSet 的实例。所以上面的方法返回的Set集合是有序的
fun createSet() {
//创建不可变Set集合
var set = setOf("java", "kotlin", "python")
println(set) //集合元素按添加顺序排列
//创建可变set集合
var mutableSet = mutableSetOf("Java", "kotlin", "Go")
println(mutableSet) //结合元素按添加顺序排列
//创建HashSet集合
var hashSet = hashSetOf("Java", "kotlin", "Go")
println(hashSet) //不保证元素顺序
//创建linkedHashSet
var linkedHashSet = linkedSetOf("Java", "kotlin", "Go")
println(linkedHashSet) //集合元素按照添加顺序排列
//创建TreeSet集合
var treeSet = sortedSetOf("Java", "Kotlin", "Go")
println(treeSet) //集合元素按照从小到大排列
}
使用Set集合
Kotlin除了Java原生Set的各种方法之外,Kotlin的Set还扩展了大量方法,在Set集合有很多方法与Array的方法功能相似,例如all、any、associate、drop、filter、find
fun setApi() {
//创建不可变的Set集合
val set = setOf("cbr650r", "dl650", "dl1050", "cbr1000rrr")
//判断所有元素是否长度都大于4
println(set.all { it.length > 4 })
//判断任一元素长度都大于4
println(set.any { it.length > 4 })
// 判断元素是否在集合中
println("cbr650r" in set)
//判断元素是否不在集合中
println("kawasaki" !in set)
//返回删除set集合前面两个元素后的集合
var dropSet = set.drop(2)
println(dropSet)
//对set集合过滤 要求集合中包含cbr
println(set.filter { "cbr" in it })//输出[cbr650r, cbr1000rrr]
//查找某个元素出现的位置
println(set.indexOf("cbr650r"))//输出0
//获取最大值
println(set.max())
//获取最小值
println(set.min())
//反转集合顺序
val reversed = set.reversed()
println(reversed)
}
遍历Set集合
Kotlin也支持使用for-in循环遍历Set,与遍历数组的基本方式相同
fun iteratorSet() {
var itSet = setOf("cbr650r", "ninjia400", "gsx250r")
for (bike in itSet) {
println(bike)
}
}
Set集合继承了Iteratable,因此可使用Iterable接口中定义的forEach()方法来遍历集合,该方法需要接受一个Lambda表达式作为参数
//foreach形式遍历
itSet.forEach({ print(it)})
由于setOf()方法返回的Set集合是有序的,因此可以通过索引来遍历Set集合,Set集合也提供了indices方法返回集合的索引区间
···
//indices形式遍历
for (i in itSet.indices) {
println(itSet.elementAt(i))
}
···
可变的Set
mutableSetOf()、hashSetOf()、linkedSetOf()、sortedSetOf()函数返回的集合都是可变的,依次是Set、HashSet、LinkedHashSet、TreeSet
添加元素
Set提供了add(Element:E)方法来添加元素。addAll(elements:Collection<E>)方法来批量添加元素
fun addElement() {
//创建可变集合
var bikeSet = mutableSetOf<String>();
//添加元素
bikeSet.add("suzuki katana")
bikeSet.add("honda cbr")
//批量添加元素
bikeSet.addAll(setOf("kawasaki ninjia"))
println(bikeSet)
}
删除元素
- remove(element:E)删除指定元素,删除成功返回true
- removeAll(elements:Collection<E>) 批量删除Set集合中的多个元素
- retainAll(elements:Collection<E>) 只保留Set集合与elements集合共有的元素
- clear() 清空集合
fun removeElement() {
var bikeSet = mutableSetOf<String>("honda", "suzuki", "kawasaki","yamaha")
//删除一个元素
bikeSet.remove("honda")
//批量删除多个元素
bikeSet.removeAll(setOf("suzuki"))
//保留与retain集合相同的元素
var retainSet = setOf<String>("kawasaki")
bikeSet.retainAll(retainSet)
println(bikeSet) //输出kawasaki
}
Set和MutableSet都包含一个iterator()方法,不可变的Set的iterator()方法返回的是iterator对象,该对象只有hasNext()和next()两个方法。MutableSet的iterator()方法返回的是MutableIterator对象,该对象除hasNext()和next()方法之外,还有一个remove()方法。该remove()方法可以在遍历的时候删除元素
也就是说,只有mutableSet的iterator对象才相当于Java的Iterator对象
fun iteratorObjSet() {
var set = mutableSetOf<String>("aa", "eyz", "abc")
var iteratorSet = set.iterator()
while (iteratorSet.hasNext()) {
val next = iteratorSet.next()
if (next.length < 3) iteratorSet.remove()
}
println(set) //输出 [eyz, abc]
}
List集合
List集合的特点:
- 集合元素有顺序
- 集合元素可重复
创建List集合
Kotlin并未真正的实现List集合,只是通过别名借用了Java体系中的ArrayList集合。
- listOf() 返回不可变的List集合 实际返回java.utils.Arrays.ArrayList的实例
- listOfNotNull(): 返回不可变的List集合。
该函数会自动去掉传入的null值
实际返回ArrayList - mutableListOf() 返回可变的MutableList集合
- arrayListOf() 返回可变的ArrayList集合
如果明确希望在程序中使用ArrayList集合,则应该使用arrayListOf()返回ArrayList集合
fun createList() {
//创建不可变的List集合
val list1 = listOf<String>("a", "b", "c", "d")
//创建不包含null值的list集合
val noNUllList = listOfNotNull("a", "b", null, "d", null, null)
println(noNUllList)//输出[a,b,d]
//创建可变List集合
val mutableList = mutableListOf<String>("c","b","a")
println(mutableList)
//创建ArrayList集合
val arrayList = arrayListOf<String>("d", "e", "f")
println(arrayList)
}
使用List
- get: List提供了get 带operator修饰的方法,因此可用"[]"运算符来访问集合元素
- indexOf():返回集合元素在List中的索引 第一次出现的位置
- lastIndexOf():返回集合元素在List中最后一次的出现位置
- subList:返回List集合的子集合
fun listApi() {
val list = listOf<String>("1","2","2","4","3")
val indexOf = list.indexOf("2")
println(indexOf) //输出1
val lastOf = list.lastIndexOf("2")
println(lastOf)
//分割list集合
val subList = list.subList(1, 3)
println(subList)
}
可变的List
mutableListOf()、arraysListOf() 函数返回的List集合都是可变的
//创建一个可变的list集合
val mutableList = mutableListOf<String>("H","E","L","L","O","W","O")
//在索引2处插入一个元素
mutableList.add(2, "I")
//删除索引1处的元素
mutableList.removeAt(1)
println(mutableList)//HILLOWO
//将索引1处的元素替换为X
mutableList[1]="X"
println(mutableList)//HILLOWO
Map集合
与Java相同,Kotlin的Map集合同样用于保存key-value对
与Java不同,Kotlin的Map集合也分为可变的和不可变的
声明和创建Map集合
Kotlin并没有真正的为JVM平台实现任何Map集合类。
- mapOf() 返回不可变的Map集合
- mutableMapOf() 返回可变的mutableMap集合
对于kotlin1.1来说,上面两个函数实际返回的是LinkedHashMap实例
- hashMapOf() 返回可变的HashMap
- LinkedMapOf() 返回可变的LinkedHashMap
- sortedMapOf() 返回可变的TreeMap集合
fun createMap() {
//创建不可变map
val map = mapOf<String, String>(
"honda" to "cbr250r", "honda" to "cbr1000rrr", "suzuki" to "gsx1000rr",
"suzuki" to "dl1050xt", "kawasaki" to "ninjia1000", "kawasaki" to "ninjiaH2"
)
//创建可变集合
val mutableMap = mutableMapOf<String, Int>("Suzuki" to 1, "Honda" to 2, "kawasaki" to 3)
//创建可变集合HashMap
val hashMap = hashMapOf<String, Int>("a" to 1)
println(hashMap.javaClass) //java.util.HashMap
//创建可变集合TreeMap
val treeMap = sortedMapOf("a" to 1)
println(treeMap.javaClass) //java.util.TreeMap
//创建可变集合LinkedHashMap
val linkedMap = linkedMapOf<String, Int>("b" to 2)
println(linkedMap.javaClass) //java.util.LinkedHashMap
}
- Kotlin需要使用to指定key-value对,to之前是key to 之后是value
使用Map
fun mapApi() {
//创建不可变map
var map = mapOf<String,Int>("Honda" to 1,"Suzuki" to 2,"KTM" to 3,"Kawasaki" to 4)
//判断是否所有key长度都大于4,value都大于0
println(map.all { it.key.length > 4 && it.value >= 0 }) //false
//判断是否任一key-value对的长度都大于4 value都大于0
println(map.any { it.key.length > 4 && it.value >= 0 }) //true
//判断键是否在map中
println("Honda" in map)
//对map集合元素进行过滤
println(map.filter { "Suzuki" in it.key })
//将每个key-value映射成新值
println(map.map { "bike${it.key}" to it.value + 2 }) //输出:[(bikeHonda, 3), (bikeSuzuki, 4), (bikeKTM, 5), (bikeKawasaki, 6)]
//根据Key获取最大值
println(map.maxByOrNull { it.key })
var map2 = mapOf<String,Int>("BMW" to 5,"QJMOTO" to 6,"Suzuki" to 2)
//集合并集
println(map + map2)//{Honda=1, Suzuki=2, KTM=3, Kawasaki=4, BMW=5, QJMOTO=6}
//集合交集
print(map-map2) //{Honda=1, Suzuki=2, KTM=3, Kawasaki=4}
}
遍历Map
Map集合由多个key-value组成,因此遍历Map集合时可通过对key-value对进行遍历,也可先遍历key,再通过key获取value遍历
kotlin的Map提供了operator修饰的get()方法,可通过[]运算符根据key来获取value
Map也可直接使用for-in循环进行遍历,遍历时循环变量的类型时Entry
fun iteratorMap() {
var map = mapOf<String,Int>("Honda" to 1,"Suzuki" to 2,"KTM" to 3,"Kawasaki" to 4)
//key-value entry遍历
for (en in map.entries) {
println(en.key + "------" + en.value)
}
//获取key 再得到value遍历
for (key in map.keys) {
println(key + "-----" + map[key])
}
//for - in 遍历map
for ((key, value) in map) {
println("$key-----$value")
}
//foreach
map.forEach { println(it.key + "------" + it.value) }
}
可变的Map
-
mutableMapOf(): 返回的是可变的Map
-
hashMapOf(): 实际返回的是HashMap
-
linkedMapOf(): 实际返回的是LinkedHashMap
-
sortedMapOf(): 实际返回的是TreeMap
-
clear() 清空所有的key-value对
-
put(key:K,value:V) 放入key-value对,如有则覆盖
-
putAll(map) 批量添加
-
remove(Key:K) 删除key-value
-
set(key,value) ==》 MutableMap可以使用'[]'来放入key-value
//创建可变map
var linkedMap = linkedMapOf<String,Int>("Honda" to 1,"Suzuki" to 2)
//add key-value
linkedMap["AUGUSTA"] = 6
println(linkedMap)
//add mote
linkedMap.putAll(mapOf("KTM" to 3,"Kawasaki" to 4))
println(linkedMap)
//remove
linkedMap.remove("KTM")
linkedMap.clear()
println(linkedMap)