数组和集合
Kotlin为数组增加了一个Array
类,因此可以用面向对象的语法使用数组。
Kotlin自己提供一套集合体系,Kotlin的集合体系抛弃了Java集合体系中的Queue
集合,但增加了可变集合和不可变集合。
与Java集合类似的是,依然存在List
、Set
、Map
三种集合类型。
1. 数组
-
创建数组
- 使用
arrayOf()
工具函数。 - 使用
arrayOfNulls()
工具函数。 - 使用
emptyArray()
工具函数。 - 使用
Array(size: Int, init: (Int) -> T)
构造器。 - 对于基本数据类型,可以使用类似
intArrayOf()
工具函数。
fun main(args: Array<String>) { // 创建指定元素的数组 val arr1 = arrayOf("Java", "Kotlin", "Swift", "Go") // 创建指定长度,元素为null的数组 val arr2 = arrayOfNulls<Double>(4) // 创建长度为0的空数组 val arr3 = emptyArray<String>() // 创建指定长度,使用Lambda表达式初始化数组元素的数组 // val arr4 = Array(5, { (it * 2 + 97).toChar() }) // 上面提示Lambda argument should be moved out of parentheses // 建议把Lambda从括号中提出来 val arr4 = Array(5) { (it * 2 + 97).toChar() } val strArr4 = Array(3) { "JamFF" } // 下面两种定义数组的类型是不一样的 val arr5: IntArray = intArrayOf(1, 2, 3)// 在JVM上是int,避免拆装箱 val arr6: Array<Int> = arrayOf(1, 2, 3)// 在JVM上是Integer }
其中
Array<T>
类要求它的元素必须是引用类型,因此如果将基本类型存入,Kotlin会自动装箱为包装类的实例,因此Kotlin提供了ByteArray
、ShortArray
、IntArray
等8种基本数据类型的数组。fun main(args: Array<String>) { // 基本数据类型的数组 val arr1 = Array(5) { it * it } // 基本数据类型的数组 val arr2 = IntArray(5) { it * it } }
- 使用
-
获取和修改数组元素
fun main(args: Array<String>) { val strArr = arrayOf("Java", "Kotlin", "Swift", "Go") // 两种获取数组元素的方式 println(strArr.get(1)) println(strArr[1]) // 推荐 // 两种方式修改数组元素 strArr.set(2, "C") strArr[3] = "C++" // 推荐 println(java.util.Arrays.toString(strArr)) }
-
使用
for-in
遍历数组
注意:使用for-in
遍历时,不与许对循环变量赋值。fun main(args: Array<String>) { val strArr = arrayOf("Java", "Kotlin", "Swift", "Go") for (str in strArr) { println(str) // str = "C"// 遍历时,不允许对循环变量赋值 } }
-
使用数组索引
-
使用数组
size
属性,创建区间,遍历索引fun main(args: Array<String>) { val strArr = arrayOf("Java", "Kotlin", "Swift", "Go") for (i in 0 until strArr.size) { println(strArr[i]) strArr[i] = "C"// 这里可以对数组赋值,但是依然不能对循环变量i赋值 } }
-
使用数组
lastIndex
属性,创建区间,遍历索引fun main(args: Array<String>) { val strArr = arrayOf("Java", "Kotlin", "Swift", "Go") for (i in 0..strArr.lastIndex) { println(strArr[i]) } }
-
使用数组
indices
属性,不需要额外创建区间对象,性能最好fun main(args: Array<String>) { val strArr = arrayOf("Java", "Kotlin", "Swift", "Go") for (i in strArr.indices) { println(strArr[i]) } }
-
同时访问数组的索引和元素
fun main(args: Array<String>) { val strArr = arrayOf("Java", "Kotlin", "Swift", "Go") for ((index, value) in strArr.withIndex()) { println("索引为${index}的元素是:$value") } }
-
-
数组的常用方法
fun main(args: Array<String>) { val arr = arrayOf(2, 4, 5, 6) // 判断是否所有元素的平方都大于20 println(arr.all { it * it > 20 }) // false // 判断是否由一个元素的平方大于20 println(arr.any { it * it > 20 }) // false val a1 = arrayOf(3, 4, 5, 6) val a2 = arrayOf(3, 4, 5, 6) // 判断数组内每个元素是否相等 println("a1和a2数组是否相等:${a1.contentEquals(a2)}") // 复制数组 val b = a1.copyOf(6) // 打印数组元素 println(b.contentToString()) // [3, 4, 5, 6, null, null] // 将b数组的索引为4(包含)到6(不包含)的元素赋值为1 b.fill(1, 4, 6) println(b.contentToString()) // [3, 4, 5, 6, 1, 1] // 排序 b.sort() println(b.contentToString()) // [1, 1, 3, 4, 5, 6] // 由于数组提供了operator修饰的plus(),所以可以使用+ println((c + d).contentToString()) // 由于数组提供了operator修饰的contains(),所以可以使用in println("Java" in c) }
2. 集合概述
Kotlin的集合类同样是由连个接口派生:Collection
和Map
,但是区别是Kotlin集合分为可变集合和不可变集合,可变集合是不可变集合的子类。
Kotlin只提供HashSet
、HashMap
、LinkedHashSet
、LinkedHashMap
、ArrayList
这5个集合实现类,并且他们都是不可变集合;有Mutable
前缀的都是可变集合;不可变集合可以通过toMutable*()
函数转换成可变集合。
3. Set集合
-
声明和创建
Set
集合-
setOf()
:不可变的Set
集合。 -
mutableSetOf()
:可变的Set
集合。 -
hashSetOf()
:可变的HashSet
集合。 -
linkedSetOf()
:可变的LinkedHashSet
集合。 -
sortedSetOf()
:可变的TreeSet
集合。
fun main(args: Array<String>) { // 不可变的Set集合,在目前Kotlin1.2中返回的是LinkedHashSet,元素的添加顺序 val set = setOf("Java", "Kotlin", "Go") // 可变的Set集合,在目前Kotlin1.2中返回的是LinkedHashSet,元素的添加顺序 val mutableSet = mutableSetOf("Java", "Kotlin", "Go") // 可变的HashSet集合,不保证元素的顺序 val hashSet = hashSetOf("Java", "Kotlin", "Go") // 可变的LinkedHashSet集合,元素的添加顺序 val linkedHashSet = linkedSetOf("Java", "Kotlin", "Go") // 可变的TreeSet集合,元素由小到大排序 val treeSet = sortedSetOf("Java", "Kotlin", "Go") }
-
-
Set
的常用方法fun main(args: Array<String>) { // 不可变的Set集合,在目前Kotlin1.2中返回的是LinkedHashSet,元素的添加顺序 val set = setOf("Java", "Kotlin", "Go") // 判读是否所有元素的长度都大于4 println(set.all { it.length > 4 }) // false // 判断是否存在一个元素长度大于四 println(set.any { it.length > 4 }) // true // 存在contains()所以可以使用in、!in运算符 println("Java" in set) // true // 返回删除前面两个元素的集合 println(set.drop(2)) // [Go] // 过滤集合元素,要求集合元素包含"li",如果不存在则返回size为0的集合 println(set.filter { "li" in it }) // [Kotlin] // 查找包含"li"的元素,存在就返回该元素,否则返回null println(set.find { "li" in it }) // Kotlin println(set.find { "JamFF" in it }) // null // 查找某个元素出现的索引位置 println(set.indexOf("Go")) // 2 // 将集合每个元素映射为新值,返回所有新值组成的Set集合 println(set.map { "学习$it" }) // [学习Java, 学习Kotlin, 学习Go] // 获取最大、最小元素 println(set.max()) // Kotlin println(set.min()) // Go // 反转集合顺序 println(set.reversed()) // [Go, Kotlin, Java] val bSet = setOf("C", "Python", "Kotlin") // 计算两个集合的交集 println(set intersect bSet) // [Kotlin] // 计算两个集合的并集 println(set union bSet) // [Java, Kotlin, Go, C, Python] // 集合相加,相当于并集 println(set + bSet) // [Java, Kotlin, Go, C, Python] // 集合相减,减去他们公共的元素 println(set - bSet)// [Java, Go] }
-
遍历
Set
-
for-in
遍历 -
forEach()
遍历 -
setOf()
是有序的,可以通过索引遍历
fun main(args: Array<String>) { val set = setOf("Java", "Kotlin", "Go") // for-in遍历 for (str in set) { println(str) } // forEach()遍历 set.forEach { println(it) } // setOf()是有序的,可以通过索引遍历 for (i in set.indices) { println(set.elementAt(i)) } }
-
-
可变的
Set
- 添加元素
fun main(args: Array<String>) { val set = mutableSetOf("Swift") set.add("Go") set.addAll(setOf("Java", "Kotlin")) println(set) // [Swift, Go, Java, Kotlin] }
- 删除元素
fun main(args: Array<String>) { val set = mutableSetOf("Kotlin", "OC", "PHP", "Perl", "Ruby", "Go") set.remove("PHP") set.removeAll(setOf("Ruby", "GO")) // 保留两个集合共有的元素 set.retainAll(setOf("Kotlin", "Python", "C++", "Perl")) println(set) // [Kotlin, Perl] set.clear() println(set.count()) // 0 }
- 添加元素
4. List集合
-
声明和创建
List
集合-
listOf()
:不可变的List
集合。 -
listOfNotNull()
:不可变的List
集合,会去掉参数中的null
值。 -
mutableListOf()
:可变的MutableList
集合。 -
arrayListOf()
:可变的ArrayList
集合。
fun main(args: Array<String>) { // [Kotlin, null, PHP, Go] println(listOf("Kotlin", null, "PHP", "Go")) // [Kotlin, PHP, Go] println(listOfNotNull("Kotlin", null, "PHP", "Go")) val mutableList = mutableListOf("Kotlin", null, "PHP", "Go"); println(mutableList) // [Kotlin, null, PHP, Go] // mutableListOf在Kotlin1.2中,返回的其实也是ArrayList println(mutableList.javaClass) // class java.util.ArrayList // [Kotlin, null, PHP, Go] println(arrayListOf("Kotlin", null, "PHP", "Go")) }
-
-
List
的常用方法Set
支持的操作,List
一般都能支持,还增加里索引操作集合元素的方法。fun main(args: Array<String>) { val list = listOf("Kotlin", "Java", "PHP", "Go") for (i in list.indices) { println(list[i]) } println(list.indexOf("Java")) // 1 // 获取List的子集,包左不包右 println(list.subList(1, 3)) // [Java, PHP] }
-
可变的
List
Set
支持的操作,List
一般都能支持,还增加里索引操作集合元素的方法。fun main(args: Array<String>) { val list = mutableListOf("Kotlin", null, "Go") list.add(2, "Java") list.removeAt(1) list[1] = "Python" list.clear() }
5. Map集合
-
声明和创建
Map
集合-
mapOf()
:不可变的Map
集合。 -
mutableMapOf()
:可变的MutableMap
集合。 -
hashMapOf()
:可变的HashMap
集合。 -
linkedMapOf()
:可变的LinkedHashMap
集合。 -
sortedMapOf()
:可变的TreeMap
集合。
fun main(args: Array<String>) { val map = mapOf("Java" to 86, "Kotlin" to 92, "Go" to 78) val mutableMap = mutableMapOf("Java" to 86, "Kotlin" to 92, "Go" to 78) val hashMap = hashMapOf("Java" to 86, "Kotlin" to 92, "Go" to 78) val linkedHashMap = linkedMapOf("Java" to 86, "Kotlin" to 92, "Go" to 78) val treeMap = sortedMapOf("Java" to 86, "Kotlin" to 92, "Go" to 78) }
-
-
Map
常用的方法fun main(args: Array<String>) { val map = mapOf("Java" to 86, "Kotlin" to 92, "Go" to 78) println(map.all { it.key.length > 4 && it.value > 80 }) // false println(map.any { it.key.length > 4 && it.value > 80 }) // true println("Java" in map) // true println(map.filter { "li" in it.key }) // {Kotlin=92} println(map.maxBy { it.key }) // Kotlin=92 println(map.minBy { it.value }) // Go=78 val mapB = mapOf("Lua" to 67, "Kotlin" to 92, "PHP" to 73) println(map + mapB) // {Java=86, Kotlin=92, Go=78, Lua=67, PHP=73} println(map - map) // {Java=86, Kotlin=92, Go=78} }
最后的相减没有搞明白,认为应该输出
{Java=86, Go=78}
,哪怕是写成map - map
,输出结果还是{Java=86, Kotlin=92, Go=78}
,希望大神赐教。 -
遍历
Map
四种常用的遍历方式
fun main(args: Array<String>) { val map = mapOf("Java" to 86, "Kotlin" to 92, "Go" to 78) for (en in map.entries) { println("${en.key}->${en.value}") } for (key in map.keys) { println("$key->${map[key]}") } for ((key, value) in map) { println("$key->$value") } map.forEach { println("${it.key}->${it.value}") } }
-
可变的
Map
fun main(args: Array<String>) { val map = mutableMapOf("OC" to 96, "PHP" to 3400, "Ruby" to 5600, "Go" to 5600) map["Swift"] = 9000 map.put("OC", 8600)// 和上面[]效果一致 map.remove("PHP") map.putAll(mapOf("Java" to 84, "Python" to 67)) map.clear() }
重点
- 数组
-
Set
、List
、Map
三种集合的使用 - Kotlin区别Java存在不可变集合
- Kotlin的集合类较Java有更多的API