Kotlin集合
# Koltin集合概述
Kotlin 标准库提供了基本集合类型的实现: set、list 以及 map。 一对接口代表每种集合类型:
- 一个 只读 接口,提供访问集合元素的操作
- 一个 可变 接口,通过写操作扩展相应的只读接口:添加、删除及更新其元素
请注意,更改可变集合不需要它是以 var
(opens new window) 定义的变量:写操作修改同一个可变集合对象,因此引用不会改变。 但是,如果尝试对 val
集合重新赋值,你将收到编译错误。
fun main() {
//sampleStart
val numbers = mutableListOf("one", "two", "three", "four")
numbers.add("five") // 这是可以的
println(numbers)
// numbers = mutableListOf("six", "seven") // 编译错误
//sampleEnd
}
2
3
4
5
6
7
8
下面是 Kotlin 集合接口的图表:
Kotlin 和 Java 一样有三种集合类型:List、Set 和 Map,它们的含义分别如下:
List
以固定顺序存储一组元素,元素可以重复。Set
存储一组互不相等的元素,通常没有固定顺序。Map
存储 键-值 对的数据集合,键互不相等,但不同的键可以对应相同的值。
不难发现,每个不可变集合都有对应的可变集合,也就是以mutable为前缀的集合
从 Java 到 Kotlin,这三种集合类型的使用有哪些变化呢?我们依次看看:
创建方式 | 示例 | 说明 | 是否可变 |
---|---|---|---|
arrayListOf mutableListOf | val array = arrayListOf val array = mutableListOf | - 必须指定元素类型 | 可变 |
listOf | val array = listOf | - 必须指定元素类型 - 必须指定初始化数据元素 | 不可变 |
arrayMapOf<K,V>() mutableMapOf<K,V> 相同元素类型的字典 | val array= arrayMapOf(Pair("key","value")) val array= mutableMapOf() | - 初始元素使用Pair包装 | 可变 |
mapOf | val array= mapOf(Pair("key","value")) | - 元素使用Pair包装 - 必须指定初始元素 | 不可变 |
arraySetOf mutableSetOf | val array= arraySetOf val array= mutableSetOf | - 会对元素自动去重 | 可变 |
setOf | val array= arraySetOf | - 对元素自动去重 - 必须指定元素类型。 | 不可变 |
# Collection
Collection
(opens new window) 是集合层次结构的根。这个接口表示一个只读集合的共同行为:检索大小、 检测是否为成员等等。 Collection
继承自 Iterable <T>
接口,它定义了迭代元素的操作。可以使用 Collection
作为适用于不同集合类型的函数的参数。对于更具体的情况,请使用 Collection
的继承者: List
(opens new window) 与 Set
(opens new window)。
fun printAll(strings: Collection<String>) {
for(s in strings) print("$s ")
println()
}
fun main() {
val stringList = listOf("one", "two", "one")
printAll(stringList)
val stringSet = setOf("one", "two", "three")
printAll(stringSet)
}
2
3
4
5
6
7
8
9
10
11
12
MutableCollection
(opens new window) 是一个具有写操作的 Collection
接口,例如 add
以及 remove
。
fun List<String>.getShortWordsTo(shortWords: MutableList<String>, maxLength: Int) {
this.filterTo(shortWords) { it.length <= maxLength }
// throwing away the articles
val articles = setOf("a", "A", "an", "An", "the", "The")
shortWords -= articles
}
fun main() {
val words = "A long time ago in a galaxy far far away".split(" ")
val shortWords = mutableListOf<String>()
words.getShortWordsTo(shortWords, 3)
println(shortWords)
}
2
3
4
5
6
7
8
9
10
11
12
13
# List
list集合,Kotlin提供了如下函数来创建list集合
listOf(); 返回不可变的集合
listOfNull(); 返回不可变集合,和前一个函数的唯一的区别是,该函数会自动去掉传入的null,也就是说返回的时候不会返回null,会过滤掉。
mutableListOf(); 该函数返回可变的MutableListOf()集合
凡是涉及到增删改的,都必须由MutableList来完成:
# 不可变集合
val strings = listOf("one", "two", "one") // 不可以对strings进行增删改查操作
# 可变集合
val numbers = mutableListOf<Int>(1, 2, 3, 4) // 可以对numbers进行增删改查操作
val numbers = arrayListOf<Int>(1, 2, 3)
2
不可变的
List类型
集合的初始化使用:listOf函数可变的
List类型
集合的初始化使用:mutableListOf函数
使用list的方法,工具类和Java很相似,具体的可以自己尝试一下。
# Set集合
容器内部的元素不按顺序排列,因此无法按照下标进行访问;
容器内部的元素存在唯一性,通过哈希值校验是否存在相同的元素,如果存在则覆盖之;
set集合,Kotlin提供了如下函数来创建Set集合
setOf, linkedSetOf是有序的, hashSetOf和sortedSetOf是无序的
setOf()
;该函数返回不可变的Set集合,该集合可以接收0个或多个参数,这些参数将作为集合的元素。
mutableSet0f()
:该函数返回可变的MutableSet集合,
hashSetOf()
:该函数返回可变的HashSet集合,
linkedSetOf()
:该函数返回可变的LinkedHashSet集合。
sortedSetOf()
:该函数返回可变的TreeSet集合, 用法同下。
# 不可变集合
val hello = setOf("H", "e", "l", "l", "o")//自动过滤重复元素
>> println(hello) = H", "e", "l", "o"
2
3
# 可变集合
val hello = mutableSetOf("H", "e", "l", "l", "o") //自动过滤掉重复元素
>> println(hello) = H", "e", "l", "o", "r", "l", "d"
2
3
- 不可变的
set类型
集合的初始化使用:setOf函数 - 可变的
set类型
集合的初始化使用:mutableSetOf函数
# set工具方法
all, any, associateBy 和数组的一样,用法也一样就不解释了。
set.drop(2) 返回删除set集合前面两个元素后的集合。
set.filter({"java" in it}) 对set集合进行过滤,返回包含java的集合。
set.find({"java" in it}) 如果集合里元素有可以包含java的返回true,否者返回false
set.add; set.remove; set.clear ...跟java一样。(set集合不允许重复,java也是一样)
还有去两个集合的交集,并集等等。
# 迭代器的使用
// set集合使用
val set = mutableSetOf<Int>(1, 2, 3, 1, 5, 5) // 可以对numbers进行增删改查操作
set.add(6)
println(set)
println("isEmpty: ${set.isEmpty()}")
println("contains: ${set.contains(0)}")
println("indexOf: ${set.indexOf(1)}")
println("lastIndexOf: ${set.lastIndexOf(5)}")
// 迭代器使用
val iterator = set.iterator()
iterator.forEach {
println("it: $it")
}
2
3
4
5
6
7
8
9
10
11
12
13
# Map字典
mapOf(); 该函数返回不可变的Map集合。
mutableMapOf(); 该函数返回可变的MutableMap集合。
其实mapOf() 返回的是LinkedHashMap()。
hashMapOf(); 返回可变的HashMap()集合。
linkedMapOf(); 返回可变的LinkedHashMap集合。
注意 增删操作必须由MutableMap来完成:
# 不可变集合
val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 1)
>> println("${numbersMap.keys}")= key1,key2,key3,key4
>> println("${numbersMap.values}") = 1,2,3,1
2
3
4
5
# 可变集合
val numbersMap = mutableMapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 1)
>> println("${numbersMap.keys}")= key1,key2,key3,key4
>> println("${numbersMap.values}") = 1,2,3,1
2
3
4
5
- 不可变的
map类型
集合的初始化使用:mapOf函数 - 可变的
map类型
集合的初始化使用:mutableMapOf函数
# 遍历map
map还可以用 map[key] = value
, 来代替map.put("key", value)
for(en in map.entries) {}
for(key in map.keys) {}
for(value in map.value) {}
2
3
4
5
到这里kotlin的数组和集合基本的用法基本上讲完了,其实和java的数组和集合基本相似,就是多了一些可变集合和不可变集合,以及提供的方法更多了一些,方便我们开发。其实kotlin自己并没有实现任何集合与数组都是调用java的。所以对于最求性能的开发者来说完全可以按照java的结合的每个的优点缺点来调用就好。
# Sequence
除了集合 Kotlin 还引入了一个新的容器类型 Sequence
,它和 Iterable
一样用来遍历一组数据并可以对每个元素进行特定的处理,先来看看如何创建一个 Sequence
。
创建
- 类似
listOf()
,使用一组元素创建:
🏝️ sequenceOf("a", "b", "c")
1
2Kotlin
- 使用
Iterable
创建:
🏝️ val list = listOf("a", "b", "c")<br/> list.asSequence()
1
2
3Kotlin
这里的
List
实现了Iterable
接口。- 类似
使用 lambda 表达式创建:
// 👇 第一个元素 val sequence = generateSequence(0) { it + 1 }<br/> // 👆 lambda 表达式,负责生成第二个及以后的元素,it 表示前一个元素
1
2
3Kotlin
这看起来和 Iterable
一样呀,为啥要多此一举使用 Sequence
呢?在下一篇文章中会结合例子展开讨论。
【参考链接】
- [1] 简书-苗小帅.Kotlin之数组和集合.https://www.jianshu.com/p/6d95db6e9f87
- [2] Kotlin集合概述.https://www.kotlincn.net/docs/reference/collections-overview.html