Kotlin数组

2

Kotlin数组

  在前面已经介绍了Kotlin的运算符和流程控制语句,这里主要介绍Kotlin的数组

创建数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Kotlin创建数组有三种常见方式
// 使用Array创建数组,创建时指定数组的大小和初始值,其中初始值通过一个函数映射定义,也可以使用lambda表达式,在函数映射或lambda表达式中it为数组的索引,根据返回值的类型确定数组的类型
// 使用arrayOf创建数组,直接给数组赋值
// 使用arrayOfNulls创建可以为空的数组,创建时指定数组的大小
fun main() {
val arr1 = Array(5, arrInit())
for ((idx, x) in arr1.withIndex()) { println("arr1[${idx}] = ${x}") }

val arr2 = Array(5) { "arr2[${it}] = ${it * 2}" }
for (x in arr2) { println(x) }

val arr3 = arrayOf(0, 2, 4, 6, 8)
for ((idx, x) in arr3.withIndex()) { println("arr3[${idx}] = ${x}") }

val arr4 = arrayOfNulls<Int>(5)
for ((idx, x) in arr4.withIndex()) { println("arr4[${idx}] = ${x}") }

}

fun arrInit(): (Int) -> Int = { it -> it * 2 }

1

二维数组

// 二维数组和一维数组的创建方法类似,也有三种创建方法。但是第一种方法中,it要指向一个新的一维数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
fun main() {
val arr1 = Array(3) { it1 -> Array(4) {it1 * 4 + it} }
for ((idx1, x) in arr1.withIndex()) {
for ((idx2, y) in x.withIndex()) {
print("arr1[${idx1}][${idx2}] = ${y} ")
}
println()
}

println("------------------------------------------------------------")

val arr2 = arrayOf(arrayOf(0, 1, 2, 3), arrayOf(4, 5, 6, 7), arrayOf(8, 9, 10, 11))
for ((idx1, x) in arr2.withIndex()) {
for ((idx2, y) in x.withIndex()) {
print("arr2[${idx1}][${idx2}] = ${y} ")
}
println()
}

println("------------------------------------------------------------")

val arr3 = Array(3) { arrayOfNulls<Int>(4) }
for ((idx1, x) in arr3.withIndex()) {
for ((idx2, y) in x.withIndex()) {
print("arr3[${idx1}][${idx2}] = ${y} ")
}
println()
}
}

4

确定类型数组

// 除了上面介绍的使用Array和arrayOf创建数组以外,还可以指定数组的类型,使用IntArray或者intArrayOf创建Int类型的数组,Byte、Short、Long、Char、Float、Double、Boolean同理
// 正是因为arrayOf没有指定元素的类型,因此可以放入不同的元素

1
2
3
4
5
6
7
8
9
10
11
12
13
fun main() {
val arr1 = arrayOf(0, 2.0, '4', 6.toShort(), "8")
for ((idx, x) in arr1.withIndex()) { println("arr1[${idx}] = ${x}") }

val arr2 = IntArray(5) {it * 2}
for ((idx, x) in arr2.withIndex()) { println("arr2[${idx}] = ${x}") }

val arr3 = doubleArrayOf(0.0, 2.0, 4.0, 6.0, 8.0)
for ((idx, x) in arr3.withIndex()) { println("arr3[${idx}] = ${x}") }

val arr4 = charArrayOf('0', '2', '4', '6', '8')
for ((idx, x) in arr4.withIndex()) { println("arr4[${idx}] = ${x}") }
}

4

数组高阶操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
// Kotlin中的数组和Java中的差异很大,具有非常多的高阶操作,有些类似于其他语言中的集合框架,如C++中的vector,Java中的ArrayList,Python中的list,这里将常用的一些操作介绍给大家。
fun main() {
val arr1 = arrayOf(28, 10, 50, 40, 20)

// copyOf函数,是复制一个新的数组,和原数组内容相同,但是地址不同,修改原数组,新数组不会改变
val arr2 = arr1.copyOf()
arr1[0]++
for ((idx, x) in arr2.withIndex()) { print("arr2[${idx}] = ${x} ") }
println()

// 这是直接赋值操作,可以看出两个指针指向同一个地址,因此修改原数组,新数组也发生变化
val arr3 = arr1
arr1[0]++
for ((idx, x) in arr3.withIndex()) { print("arr3[${idx}] = ${x} ") }
println()

// silce切片操作,取出切片范围内的元素形成新List集合,不是数组,通过对象.javaClass可以查看对象的类型。但是要注意两边都是闭区间
val arr4 = arr1.slice(0..2)
println("${arr4.javaClass}类型的arr4 = ${arr4}")

// plus追加操作,在原数组后面追加元素形成新数组,原数组不会发生变化,可以是单个元素,也可以是数组或者集合
val arr5 = arr1.plus(arrayOf(70, 60))
for ((idx, x) in arr5.withIndex()) { print("arr5[${idx}] = ${x} ") }
println()
println("arr5的大小为 = ${arr5.size}")

// contains判断数组中是否包含元素,返回Boolean类型true或者false
val arr6 = arr1.contains(50)
println("arr1是否包含50 = ${arr6}")
val arr7 = arr1.contains(60)
println("arr1是否包含60 = ${arr7}")

// all判断数组中的元素是否都满足某一条件,any判断数组中的元素是否存在满足某一条件,其中条件是一个谓词,常用lambda表达式
val arr8 = arr1.all { it > 1 }
println("arr1是否全都大于1 = ${arr8}")
val arr9 = arr1.any { it > 1 }
println("arr1是否存在大于1 = ${arr9}")

// 判断数组中满足条件的元素个数,其中条件是一个谓词,常用lambda表达式
val arr10 = arr1.count { it > 2 }
println("arr1中大于1的数有 = ${arr10}个")

// drop在原数组中删除前面n个元素组成新List集合,原数组不发生变化
val arr11 = arr1.drop(2)
println("arr1删去前两个元素为 = ${arr11}")

// dropWhile在原数组中删除前面符合条件的所有元素组成新List集合,原数组不发生变化,其中条件是一个谓词,常用lambda表达式
val arr12 = arr1.dropWhile { it > 15 }
println("arr1从前面删除所有大于15的元素 = ${arr12}")

// dropLast在原数组中删除后面n个元素组成新List集合,原数组不发生变化
val arr13 = arr1.dropLast(2)
println("arr1删除后两个元素为 = ${arr13}")

// dropLastWhile在原数组中删除后面符合条件的所有元素组成新List集合,原数组不发生变化,其中条件是一个谓词,常用lambda表达式
val arr14 = arr1.dropLastWhile { it > 15 }
println("arr1从后面删除所有大于15的元素 = ${arr14}")

// reversed将原数组逆序排列组成新List集合,原数组不发生变化。如果想直接修改原始数组,使用reverse方法
val arr15 = arr1.reversed()
println("arr1逆序排列为 = ${arr15}")

// sorted将原数组从小到大排序组成新List集合,原数组不发生变化。如果想直接修改原始数组,使用sort方法
val arr16 = arr1.sorted()
println("arr1从小到大排列为 = ${arr16}")

// sortedDescending将原数组从大到小排序组成新List集合,原数组不发生变化。如果想直接修改原始数组,使用sortDescending方法
val arr17 = arr1.sortedDescending()
println("arr1从大到小排列为 = ${arr17}")

// sortedBy将原数组根据条件从小到大排序组成新List集合,原数组不发生变化,其中条件是一个谓词,常用lambda表达式。如果想直接修改原始数组,使用sortBy方法
val arr18 = arr1.sortedBy { Math.abs(it - 36) }
println("arr1中的按照元素减36并取绝对值从小到大排列为 = ${arr18}")

// sortedByDescending将原数组根据条件从大到小排序组成新List集合,原数组不发生变化,其中条件是一个谓词,常用lambda表达式。如果想直接修改原始数组,使用sortByDescending方法
val arr19 = arr1.sortedByDescending() { Math.abs(it - 36) }
println("arr1中的按照元素减36并取绝对值从大到小排列为 = ${arr19}")

// filter删除数组中所有满足条件的元素,其中条件是一个谓词,常用lambda表达式
val arr20 = arr1.filter { it > 25 }
println("arr1删除大于25的所有元素为 = ${arr20}")

// forEach将数组中的元素取出,进行某些操作。forEachIndexed将数组中的索引和对应的元素都取出,进行某些操作,其中操作,常用lambda表达式
arr1.forEachIndexed { index, i -> print("arr1[${index}] = ${i} ") }
println()

// first返回数组的第一个元素
val arr21 = arr1.first()
println("arr1的第一个元素为 = ${arr21}")

// first带有谓词作为参数,返回数组第一个符合条件的元素,其中谓词常用lambda表达式
val arr22 = arr1.first() {it > 30}
println("arr1中大于30的第一个元素为 = ${arr22}")

// indexOfFirst返回数组第一个符合条件的元素的索引,其中谓词常用lambda表达式
val arr23 = arr1.indexOfFirst { it > 30 }
println("arr1中大于30的第一个元素的索引为 = ${arr23}")

// last返回数组的最后一个元素
val arr24 = arr1.last()
println("arr1的最后一个元素为 = ${arr24}")

// last带有谓词作为参数,返回数组最后一个符合条件的元素,其中谓词常用lambda表达式
val arr25 = arr1.last() {it > 30}
println("arr1中大于30的最后一个元素为 = ${arr25}")

// indexOfLast返回数组最后一个符合条件的元素的索引,其中谓词常用lambda表达式
val arr26 = arr1.indexOfLast() { it > 30 }
println("arr1中大于30的最后一个元素的索引为 = ${arr26}")

// indexOf返回数组中某元素的索引
val arr27 = arr1.indexOf(10)
println("arr1中1的索引为 = ${arr27}")

// isEmpty判断数组是否为空,即大小是否为0
val arr28 = arr1.isEmpty()
println("arr1是否为空 = ${arr28}")

// isNotEmpty判断数组是否不为空,即大小是否不为0
val arr29 = arr1.isNotEmpty()
println("arr1是否不为空 = ${arr29}")

// getOrElse获取指定位置的元素,如果不存在则返回映射对应的元素,其中映射常用lambda表达式
val arr30 = arr1.getOrElse(10) { it * 2 }
println("arr1[10]的值为 = ${arr30}")

// getOrNull获取指定位置的元素,如果不存在则返回Null
val arr31 = arr1.getOrNull(10)
println("arr1[10]的值为 = ${arr31}")

// joinToString将元素根据映射转换为字符串,并进行组合,其中第一个参数为两个元素之间的连接符,第二个参数为第一个元素之前的字符串,第三个参数为最后一个元素之后的字符串,第四个参数为显示的元素个数
val arr32 = arr1.joinToString("->", "begin->", "->end", 4) { "${it}" }
println(arr32)

// max返回数组最大的元素
val arr33 = arr1.max()
println("arr1的最大值为 = ${arr33}")

// maxBy根据条件返回数组最大的元素,其中条件常用lambda表达式
val arr34 = arr1.maxBy { Math.abs(it - 36) }
println("arr1元素减36并取绝对值的最大值为 = ${arr34}")

// min返回数组最小的元素
val arr35 = arr1.min()
println("arr1的最小值为 = ${arr35}")

// minBy根据条件返回数组最小的元素,其中条件常用lambda表达式
val arr36 = arr1.minBy { Math.abs(it - 36) }
println("arr1元素减36并取绝对值的最大值为 = ${arr36}")

// random随机返回数组中的任意一个元素
val arr37 = arr1.random()
println("arr1随机取出一个元素为 = ${arr37}")

// random根据种子点随机返回数组中的任意一个元素
val arr38 = arr1.random(Random(20))
println("arr1随机取出种子点为20的元素为 = ${arr38}")

// reduce将元素进行迭代计算后返回计算的结果,在本例中,数组为[30, 10, 50, 40, 20],先将30赋值给x,10赋值给y,进行2x + y操作得到70,然后将70赋值给x,50赋值给y,得到190,同理得到420,最后得到860
val arr39 = arr1.reduce() { x, y -> 2 * x + y }
println("arr1迭代求解2 * x + y的值为 = ${arr39}")

// sum返回数组所有元素之和
val arr40 = arr1.sum()
println("arr1元素之和为 = ${arr40}")

// sumBy返回数组所有元素映射结果之和,其中映射常用lambda表达式
val arr41 = arr1.sumBy { it * it }
println("arr1元素平方之和为 = ${arr41}")

// zip将两个数组进行结合形成新List集合,结合后集合每个元素是一个Pair二元组,二元组对象具有.first和.second两个属性,可以获取对应的值
val arr42 = arr1.zip(arr1.reversed())
print("将arr1和其逆序组合后, ")
arr42.forEachIndexed { index, i -> print("arr42[${index}] = <${i.first} ${i.second}> ") }
println()

// map将数组中的每个元素按照映射形成新List集合,其中映射常用lambda表达式
val arr43 = arr1.map { it * 2 }
println("arr1所有元素乘2为 = ${arr43}")

// union将两个数组求并集形成Set集合
val arr44 = arr1.union(arr43)
println("arr1和arr1乘2的并集为 = ${arr44}")

// intersect将两个数组求交集形成Set集合、此外还有subtract求差集
val arr45 = arr1.intersect(arr43)
println("arr1和arr1乘2的交集为 = ${arr45}")

// toList根据数组创建List集合
val arr47 = arr1.toList()
println("${arr47.javaClass}类型的arr47 = ${arr47}")

// toMutableList根据数组创建可变List集合
val arr48 = arr1.toMutableList()
println("${arr48.javaClass}类型的arr48 = ${arr48}")

// toSet根据数组创建Set集合
val arr49 = arr1.toSet()
println("${arr49.javaClass}类型的arr49 = ${arr49}")

// toMutableSet根据数组创建可变Set集合
val arr50 = arr1.toMutableSet()
println("${arr50.javaClass}类型的arr50 = ${arr50}")

// toHashSet根据数组创建HashSet集合
val arr51 = arr1.toHashSet()
println("${arr51.javaClass}类型的arr51 = ${arr51}")

// toSortedSet根据数组创建toSortedSet集合
val arr52 = arr1.toSortedSet()
println("${arr52.javaClass}类型的arr52 = ${arr52}")

// fill将数组用指定元素进行填充,其中第一个参数为指定的元素,第二个参数和第三个参数为起始和终止的位置,默认填充所有元素
arr1.fill(0)
print("将arr1全部填充为0后, ")
for ((idx, x) in arr1.withIndex()) { print("arr1[${idx}] = ${x} ") }
println()
}

4

Kotlin小结

  数组是我们存放数据的好方法,就如同抽屉一样,每一个抽屉都放置同样的物品,数组的学习非常重要,无论以后从事什么样的研究,数组的使用都是必不可少的,因此需要熟练掌握。

-------------本文结束感谢您的阅读-------------
0%