Kotlin为数组增加了一个Array类,为元素是基本类型的数组增加了XxxArray类。
Kotlin自己提供了一套集合体系,Kotlin的集合体系抛弃了Java集合体系中的Queue集合,增加了可变集合和不可变集合的概念。
Kotlin的List代表有序、集合元素可重复的集合;Set代表无序、集合元素不可重复的集合;Map则采用key-value对的形式存储数据,每项数据都由key-value对组成。
Kotlin的数组使用Array<T>类代表,Kotlin数组就是一个Array类的实例,所以Kotlin数组也算是引用类型。
一、创建数组
Kotlin创建数组就是创建Array<T>类的实例,Kotlin即可允许通过Array<T>类的构造器来创建实例,也可以通过arrayOf()等工具函数来创建实例。
创建数组的两种方式:
- 使用arrayOf()、arrayOfNulls()、emptyArray()工具函数;
- 使用Array(size:Int,init:(Int)->T)构造器
//创建包含指定元素的数组(相当于Java数组的静态初始化)
var arr1 = arrayOf("Java", "Kotlin", "Swift", "Go")
var intArr1 = arrayOf(2, 4, 500, -34)
//创建指定长度、元素为null的数组(相当于Java数组的动态初始化)
var arr2 = arrayOfNulls<Double>(5)
var intArr2 = arrayOfNulls<Int>(6)
//创建长度为0的空数组
var arr3 = emptyArray<String>()
var intArr3 = emptyArray<Int>()
//创建指定长度、使用Lambda表达式初始化数组元素的数组
var arr4 = Array(5,{ (it * 2 + 97).toChar() })
var strArr4=Array(6,{"hello"})
- 使用arrayOf()函数:无须显式指定数组的长度,但需要依次列出每个数组元素。这种方式相当于Java数组的静态初始化。
- 使用arrayOfNulls()函数:需要显式指定数组的长度,数组元素全部被初始化为null。这种方式相当于Java数组的动态初始化。
- 使用emptyArray()函数:创建一个长度为0的空数组。
- 使用Array(size:Int,init:(Int)->T)构造器:需要显式指定数组的长度,并可通过Lambda表达式来动态计算各数组的值。
Kotlin专门提供了ByteArray、ShortArray、IntArray、LongArray、CharArray、FloatArray、DoubleArray、BooleanArray,分别用于映射Java的byte[]、short[]、int[]、long[]、char[]、float[]、double[]、boolean[]这8种基本类型的数组。
//创建包含指定元素的数组
var intArr = intArrayOf(2, 4, 30, -5)
var doubleArr = doubleArrayOf(2.3, 3.5, -3.0)
//创建指定长度、使用Lambda表达式初始化数组元素的数组
var intArr2 = IntArray(5, { it * it })
var charArr = CharArray(5, { (it * 2 + 97).toChar() })
println(Arrays.toString(intArr2))
println(Arrays.toString(charArr))
输出结果:
[0, 1, 4, 9, 16]
[a, c, e, g, i]
基本类型的元素不允许为null。
二、使用数组
数组的常用方法就是访问数组元素,包括对数组元素进行赋值和取出数组元素的值。
访问数组元素是通过字啊数组引用变量后紧跟一个方括号([])
实现的,方括号里是数组元素的索引值。
kotlin语言的数组索引值同样是从0
开始的。
//创建包含指定元素的数组
var strArr = arrayOf("Kotlin", "Java", "Go", "Swift")
//使用两种方式获取数组元素
println(strArr[1])
println(strArr.get(1))
//使用两种方式修改数组元素
strArr[1] = "Python"
strArr.set(2, "Ruby")
println(Arrays.toString(strArr))
输出结果:
Java
Java
[Kotlin, Python, Ruby, Swift]
如果访问数组元素时指定的索引小于0,或者大于或等于数组的长度,编译时不会出错,运行时会出现java.lang.ArraylndexOutOfBoundsException: N
异常。
三、使用for-in循环遍历数组
Kotlin的for-in循环可自动遍历数组的每个元素。
var languages= arrayOf("C/C++","Java","Python","Kotlin")
for (language in languages) {
println(language)
}
输出结果:
C/C++
Java
Python
Kotlin
使用for-in循环来遍历数组元素或集合元素时,不允许对循环变量进行赋值。
四、使用数组索引
Kotlin的数组还提供了一个indices属性
,该属性即可返回数组的索引区间。
var languages= arrayOf("C/C++","Java","Python","Kotlin")
for (i in languages.indices) {
println(languages[i])
}
输出结果:
C/C++
Java
Python
Kotlin
还可以使用in、!in来检查某个索引是否位于数组的索引区间内。
var i = java.util.Random().nextInt(10)
println(i in languages.indices)
Kotlin提供了一个lastIndex
属性,该属性用于返回数组最后一个元素的索引值。
println(languages.lastIndex)
println(languages.size-1==languages.lastIndex)
输出结果:
3
true
还可以使用数组的withIndex()
方法来同时访问数组的索引和元素,该方法返回一个Iterable对象
,该对象的所有元素都是IndexedValue。
var languages = arrayOf("C/C++", "Java", "Python", "Kotlin")
for ((index, value) in languages.withIndex()) {
println("索引为${index}的元素是:${value}")
}
输出结果:
索引为0的元素是:C/C++
索引为1的元素是:Java
索引为2的元素是:Python
索引为3的元素是:Kotlin
五、数组的常用方法
//定义一个数组
var arr = arrayOf(2, 4, 5, 6)
//判断是否所有元素的平方都大于20
println(arr.all { it * it > 20 })
//判断是否任一元素的平方大于20
println(arr.any { it * it > 20 })
//根据数组元素来计算<K,V>对,返回所有<K,V>对组成的Map集合
//K是数组元素+10,V是数组元素的平方
var result = arr.associate { it + 10 to it * it }
println("result为:${result}")
//创建一个可变Map集合,用于追加根据数组计算出来的key=value对
var map = mutableMapOf(1 to 100, 2 to 120, -1 to 130)
//将计算出来的key、value对添加到map集合中
arr.associateByTo(map, { it * it })
println("map为:${map}")
//计算数组所有元素的总和
println(arr.fold(0, { acc, e -> acc + e }))
//定义一个a数组
var a = arrayOf(3, 4, 5, 6)
//定义一个a2数组
var a2 = arrayOf(3, 4, 5, 6)
//a数组和a2数组的长度相等,每个元素依次相等,将输出true
println("a数组和a2数组是否相等:${a.contentEquals(a2)}")
//通过赋值a数组,生成一个新的b数组
var b=a.copyOf(6)
println("a数组和b数组是否相等:${a.contentEquals(b)}")
//输出b数组的元素
println("b数组的元素为:${b.contentToString()}")
//将b数组的第五个元素到第七个元素赋值为1
b.fill(1,4,6)
//输出b数组的元素
println("b数组的元素为:${b.contentToString()}")
//对b数组进行排序
b.sort()
//输出b数组的元素
println("b数组的元素为:${b.contentToString()}")
输出结果:
false
true
result为:{12=4, 14=16, 15=25, 16=36}
map为:{1=100, 2=120, -1=130, 4=2, 16=4, 25=5, 36=6}
17
a数组和a2数组是否相等:true
a数组和b数组是否相等:false
b数组的元素为:[3, 4, 5, 6, null, null]
b数组的元素为:[3, 4, 5, 6, 1, 1]
b数组的元素为:[1, 1, 3, 4, 5, 6]
六、多维数组
所谓的多维数组其实都是一维数组,只要让数组的元素又是数组,就变成了多维数组。
//把a当成一维数组进行初始化,初始化a是一个长度为4的数组
//a数组的元素又是Array<Int>类型
var a = arrayOfNulls<Array<Int>>(4)
//把a数组当成一维数组,遍历a数组的每个数组元素
for (i in a.indices) {
println(a[i])
}
//初始化a数组的第一个元素
a[0]= arrayOf(2,5)
//访问a数组的第一个元素所指数组的第二个元素
a[0]?.set(1, 6)
//a数组的第一个元素是一个一维数组,遍历这个一维数组
for (i in a[0]!!.indices) {
println(a[0]?.get(i))
}
输出结果:
null
null
null
null
2
6
Kotlin也支持同时初始化两个维数的用法。
//同时初始化二维数组的两个维数
var b=Array<IntArray>(3,{IntArray(4,{0})})
Kotlin也可使用arrayOf()方法来初始化二维数组。
var arr = arrayOf(arrayOfNulls<String>(3), arrayOf("hello"))
七、数组的应用
fun main(args: Array<String>) {
//测试将一个浮点数分解成整数部分和小数部分。
println(divide(3544513.1254).contentToString())
//测试把一个4位数的数字字符串变成汉字字符串
println(toHanStr("6045"))
}
/**
* 把一个浮点数分解成整数部分和小数部分字符串
*/
fun divide(num: Double): Array<String> {
var zheng = num.toLong()
var xiao = Math.round((num - zheng) * 100)
return arrayOf(zheng.toString(), xiao.toString())
}
val hanArr = arrayOf("零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖")
val unitArr = arrayOf("十", "百", "千")
/**
* 把一个4位的数字字符串变成汉字字符串
*/
fun toHanStr(numStr: String): String {
var result = ""
val numLen = numStr.length
//依次遍历数字字符串的每一位数字
for (i in 0 until numLen) {
//把Char型数字转换为Int型数字
//所以把Char型数字减去48得到Int型数字
var num = numStr[i].toInt() - 48
if (i != numLen - 1 && num != 0) {
result += hanArr[num] + unitArr[numLen - 2 - i]
} else {
result += hanArr[num]
}
}
return result
}
输出结果:
[3544513, 13]
陆千零肆十伍
网友评论