预告:在程序的世界里,集合是一个无法缺少的类型。要是没有集合,很难想象面对一大堆相同类型的数据,我们该如何管理和使用。同Java一样,Kotlin里也有List、Set、Map等相关集合类型,但它们的使用又有自己的独到之处。Let`t go !
集合:可以方便你处理一组数据,也可以作为值参传递给函数,和我们学过的其它变量类型一样。List、Set和Map类型的变量也分为只读和可变两种。
一 List集合
1.1 List的创建与获取
创建一个List非常简单,使用listOf函数即可创建一个List。与Java类似,我们可以使用list.get()来获取对应的元素。
fun listCreatAndGet(){
//创建List 可自动进行类型推断
val list = listOf("Jack","Jacky","Lily")
println(list.get(0))
println(list.getOrElse(2){"index 2 no data"})
println(list.getOrElse(3){"index 3 no data"})
println(list.getOrNull(1)?:"index 1 no data")
println(list.getOrNull(4))
println(list.getOrNull(4)?:"index 4 no data")
println(list)
}
//结果
Jack
Lily
index 3 no data
Jacky
null
index 4 no data
[Jack, Jacky, Lily]
listOf函数支持类型推断,我们可不显示的指明元素类型。可能细心的朋友已经发现我们除了使用常规的list.get()之外,还使用了list.getOrElse() 、list.getOrNull() 这2个函数。在Java中,如果我们使用list.get()的下标是超过List的长度的话,那么java.lang.ArrayIndexOutOfBoundsException异常就该找你谈谈了,所以我们在使用的时候也是处处小心,毕竟茶也不是那么好喝的嘛。
getOrElse : 是一个安全索引取值,它需要两个参数,第一个是索引值,第二个是能提供默认值的lambda表达式,如果索引值不存在的话,可用lambda提供的默认值来代替异常。
getOrNull : 是Kotlin提供的另一个安全索引取值函数,它返回null结果,而不是抛出异常。注意:这里如果超过索引值,它返回一个null,MD,这不是玩我么,但如果我们配合?:空默认值的话也可以实现getOrElse的效果,但getOrElse的默认值是一个表达式的值,更灵活一些。
好吧,创建和取值没问题了,我们现在尝试向list添加一个元素。使用list.add(),嗯…,函数没有。这不是玩嘛。是的,在开篇我们已经说过了,Kotlin的集合也分为只读集合和可变集合。所以,如果你需要的是可变集合,那么需要使用mutableListOf进行这样定义。
fun mutableListTest(){
val mutableList = mutableListOf("Jack","Jacky","Lily");
println(mutableList.get(0))
println(mutableList.getOrElse(2){ "index 2 no data"})
println(mutableList.getOrElse(3){"index 3 no data"})
println(mutableList.getOrNull(1)?:"index 1 no data")
println(mutableList.getOrNull(4))
println(mutableList.getOrNull(4)?:"index 4 no data")
println(mutableList)
mutableList.add("Lucy")
println(mutableList)
mutableList.add(1,"Calm")
println(mutableList)
mutableList.remove("Lily")
println(mutableList)
}
//结果
Jack
Lily
index 3 no data
Jacky
null
index 4 no data
[Jack, Jacky, Lily]
[Jack, Jacky, Lily, Lucy]
[Jack, Calm, Jacky, Lily, Lucy]
[Jack, Calm, Jacky, Lucy]
嗯…,基本用法差不多,不多说了,看代码就能理解。
如果我们需要只读列表与可变列表的转化,可以如下操作:
val list0 = mutableList.toList()
val list1 = list0.toMutableList()
1.2 List的遍历
遍历是List所常用的操作,我们需要一种能快速全部取得相关数据的操作。根据需求我们可能仅仅需要值,有时候还需要值所对应的下标。在Kotlin中提供for in、forEach、forEachIndexed对List进行遍历操作,其中forEachIndexed可取出对应的下标和值。
fun traverseList(){
val list = listOf("Jack","Jacky","Lily")
//for in 遍历
for (s in list){
print("$s ")
}
println()
//forEach遍历
list.forEach {
print("$it ")
}
println()
//forEachIndexed遍历
list.forEachIndexed{index: Int, s: String ->
print("$s at $index ")
}
}
//结果
Jack Jacky Lily
Jack Jacky Lily
Jack at 0 Jacky at 1 Lily at 2
1.3 解构
List是支持解构操作的
fun jieGouTest(){
val list = listOf("Jack","Jacky","Lily")
val (one,_,three) = list
println("$one $three ")
}
//结果
Jack Lily
1.4 List去重
List里面的数据是有可能重复的,那么我们需要对其进行去重处理该怎么办呢?我们可以使用distinct函数
fun distinctTest(){
val list1 = listOf("Jack","Jacky","Lily","Jack","Jacky")
println(list1)
val list2 = list1.distinct()
println(list2)
}
//结果
[Jack, Jacky, Lily, Jack, Jacky]
[Jack, Jacky, Lily]
二 Set集合
2.1 Set的创建和获取
fun setCreateAndGet(){
val set = setOf("Jack","Jacky","Lily")
//不支持这样取值
// set[0]
println(set.elementAt(0))
println(set.elementAtOrElse(3){"no data at index $it"})
println(set.elementAtOrNull(3)?:"no data")
}
//结果
Jack
no data at index 3
no data
与List类似,创建使用setOf来进行Set集合的创建,使用elementAt()进行取值,也支持elementAtOrElse、elementAtOrNull系列操作,结果看代码示例和结果即可。
如果需要的是可变Set,则如下定义:
fun mutableSetTest(){
val mutableSet = mutableSetOf("Jack","Jacky","Lily")
println(mutableSet)
mutableSet.add("Lucy")
println(mutableSet)
mutableSet.remove("Jack")
println(mutableSet)
}
//结果
[Jack, Jacky, Lily]
[Jack, Jacky, Lily, Lucy]
[Jacky, Lily, Lucy]
同理,Set支持只读与可变之间的转化。代码如下:
val set0 = mutableSet.toSet()
val set1 = set0.toMutableSet()
2.2 Set的遍历
Set的遍历与List类似,示例如下:
fun traverseSet(){
val set = setOf("Jack","Jacky","Lily")
//for in 遍历
for (s in set){
print("$s ")
}
println()
//forEach遍历
set.forEach {
print("$it ")
}
println()
//forEachIndexed遍历
set.forEachIndexed{index: Int, s: String ->
print("$s at $index ")
}
}
//结果
Jack Jacky Lily
Jack Jacky Lily
Jack at 0 Jacky at 1 Lily at 2
ok,看代码吧,不多说。
2.3 List与Set的相互转化
List与Set可以进行相互转化,可调用toSet转为Set集合。可调用toList转为List集合。
fun converListWithSet(){
val list = listOf("Jack","Jacky","Lily")
val set = list.toSet()
println(set)
val list1 = listOf("Jack","Jacky","Lily","Jack","Jacky")
println(list1)
val set1 = list1.toSet().toList()
println(set1)
}
//结果
[Jack, Jacky, Lily]
[Jack, Jacky, Lily, Jack, Jacky]
[Jack, Jacky, Lily]
我们可以利用Set集合元素不重复的特性,通过转化也可达到去重的效果。
三 Map集合
Map集合在Java 中的使用不算少,那么在Kotlin又是怎样的呢,一起看看吧。
3.1 Map的创建与获取
fun mapCreateAndGet(){
//使用to关键字创建键值对
val map = mapOf("Jack" to 18,"Jacky" to 20,"Lily" to 22)
println(map)
//使用Pair创建键值对
val map0 = mapOf(Pair("Jack",18), Pair("Jacky",20), Pair("Lily",22))
println(map0)
//使用[]取值运算符读取,如果键不存在则返回null
println(map["Jack"])
println(map["Calm"])
//使用getValue读取,如果键不存在则抛出异常
println(map.getValue("Jack"))
//该句因为键不存在,会抛出异常
// println(map.getValue("Calm"))
//使用getOrElse读取,如果键不存在则返回匿名函数的的结果值
println(map.getOrElse("Calm"){"no data"})
//使用getOrDefault 传递键和默认值作为参数,键不存在则返回默认值
println(map.getOrDefault("Calm","unKnow"))
}
//结果
{Jack=18, Jacky=20, Lily=22}
{Jack=18, Jacky=20, Lily=22}
18
null
18
no data
unKnow
其实蛮简单的,看注释吧。都写得明明白白的了。
创建可变Map,代码如下:
fun mutableMapTest(){
//使用to关键字创建键值对
val map = mutableMapOf("Jack" to 18,"Jacky" to 20,"Lily" to 22)
println(map)
//使用Pair创建键值对
val map0 = mutableMapOf(Pair("Jack",18), Pair("Jacky",20), Pair("Lily",22))
println(map0)
println(map.getOrPut("Calm"){20})
map.put("Calm",18)
println(map)
map += "Lucy" to 30
println(map)
}
//结果
{Jack=18, Jacky=20, Lily=22}
{Jack=18, Jacky=20, Lily=22}
20
{Jack=18, Jacky=20, Lily=22, Calm=18}
{Jack=18, Jacky=20, Lily=22, Calm=18, Lucy=30}
可以看到创建通过mutableMapOf,键值对可以使用to,也可使用Pair进行创建。存值的时候可通过put、+=操作符。这里多一个getOrPut,该函数其本质是获取,但如果键值不存在的时候,会进行添加并返回结果,如果已存在则返回已有的键对应的值,可以去试下吧,还是蛮好理解的。
四 数组
Kotlin提供各种Array,虽然是引用类型,但可以编译成Java基本类型的数据。其对应关系如下:
数组类型 | 创建函数 |
---|---|
IntArray | intArrayOf |
DoubleArray | doubleArrayOf |
LongArray | longArrayOf |
ShortArrat | shortArrayOf |
ByteArray | byteArrayOf |
FloatArray | floatArratOf |
BooleanArray | booleanArrayOf |
Array | arryOf |
使用示例如下:
fun arrayTest(){
val intArray = intArrayOf(1,2,3,4,5)
intArray.forEach {
print("$it ")
}
println()
intArray[4] = 10
intArray.forEach {
print("$it ")
}
println()
val doubleArray = doubleArrayOf(1.0,2.0,3.5,4.6)
doubleArray.forEach {
print("$it ")
}
}
//结果
1 2 3 4 5
1 2 3 4 10
1.0 2.0 3.5 4.6
ok,不用多解释了吧,数组的使用想必在Java中也不会少吧。