陣列就是一種物件,使用索引(index)提取裏面的內容。在Java中陣列裏面可以存放多個相同的資料型態。
Kotlin陣列裏號稱可以存放不同的資料型態。其實是騙人的,因為他是被宣告成 Any
fun main(args:Array<String>) {
var a:Array<Any> = arrayOf("abc", 1, 2, 3)
for (i in a.indices){
println(a[i])
}
}
Array宣告
使用 Array產生陣列物件,第一個參數為陣列的長度,第二個參數 {it->0},表示所有的原素皆填入0。另外it->可以省略
fun main(args:Array<String>){
var s1:Array<Int> =Array(5, {it -> 0}) //寫於()之內
var s2:Array<Int> =Array(5){it->10} //也可以寫於()之外
s1[4]=100
for (i in s1.indices){
println(s1[i])
}
}
空元素的陣列宣告
使用arrayOfNulls<型態>(數量) 即可產生一個陣列。此方式產生的陣列,裏面的值皆為null
var s1= arrayOfNulls<Int>(5)
若要初始化裏面的值,可使用 arrayOf<型態>(值1, 值2, …..)
var s2= arrayOf<Int>(10,20,30,40,50)
上述亦可精簡將 <Int> 刪除,讓系統自動判斷
var s3= arrayOf(10,20,30,40,50)
宣告基本型態–初始化為0
Kotlin內建一些常用的基本陣列物件,如ByteArray, IntArray, DoubleArray。
底下代碼,宣告一個s1陣列,裏面有5個空間,而且5個空間的初始值皆為 0。然後再把索引為0的空間改為95,索引1的空間改為100。
var s4=IntArray(5)
s4[0]=95
s4[1]=100
另外也可以使用 intArrayOf()將初始值置入,如下
var s5=intArrayOf(80,90,95,98,96)
宣告其他型態
如果要宣告其他型態,如String, 可以使用如下方式。此時s3裏的5個空間,初始值皆為 null
var s6= arrayOfNulls<String>(5)
如果要直接指定初始值,請依如下方式
var s7= arrayOf<String>("thomas", "anna", "John")
另外也可以將 <String> 拿掉,系統會自動判斷為字串
var s8= arrayOf("thomas", "anna", "John")
陣列存取
足一存取
fun main(args:Array<String>){
var s=intArrayOf(5,10,15,20,25)
s[0]=100
s[1]=50
println(s[0])
println(s[1])
}
for each
fun main(args:Array<String>){
var ss=intArrayOf(5,10,15,20,25)
for(s in ss){
println(s)
}
}
for (i in arrayVar.indices)
底下的 ss.indices,會產生 “0..4” 的結果
fun main(args:Array<String>){
var ss=intArrayOf(5,10,15,20,25)
for(i in ss.indices){
println(ss[i])
}
}
for (i in 0 until arrayVar.size)
底下的ss.size結果為 5,而for..in..until不包含最後一個數,所以剛好可以遍歷整個陣列
fun main(args:Array<String>){
var ss=intArrayOf(5,10,15,20,25)
for(i in 0 until ss.size){
println(ss[i])
}
}
二維陣列
二維陣列可視為一維陣列中的元素又是陣列,如下先宣告有3列,然後再宣告每一列有5行。
fun main(args:Array<String>){
var s3=Array(3, {Array(5, {0})})
s3[0][0]=10
s3[1][2]=18
s3[2][4]=60
for (row in s3){
for (col in row){
print("%2d ".format(col))
}
println()
}
}
也可以宣告成如下,每列都不等長
fun main(args:Array<String>){
var s1=arrayOf(arrayOf(1,2,3), arrayOf(4,5,6,7), arrayOf(9,10,11,12,13))
for (i in s1){
for (j in i){
print("%d ".format(j))
}
println()
}
}
動態陣列
產生空值的陣列,其實這句話很模糊。必需再加以說明。底下的代碼,都會產生5個空間的陣列,每個空間裏的值都是null。
var a1:Array<Int?> = Array(5,{null})
var a2=arrayOfNulls<Int>(5)
上面所產生的物件,可以使用下圖說明。在stack區產生了一個區域變數 a,然後於heap區產生了一個物件陣列。此物件陣列有5個空間,每個空間裏的值都是null
如果想要產生如下圖所示的陣列呢。也就是說只有stack區有一個區域變數。但heap區並沒有物件陣列產生,也就是說目前還不知道要產生多少元數的陣列,所以先讓變數 a 為null。等到日後才知道要產生多少元素,才真正生成物件陣列,這種方式又稱為動態陣列。
要產生上圖的a 變數,需用如下
var a:Array<Int>? = null
//待日後決定要產生8個元素,再用如下方式產生陣列
a=Array(5, {null})
但上述紅色的部份又出問題了,原因是陣列裏的元素不可以有空值,所以正確的寫法如下。第一個 “?” 表示元素可以為空值,第二個 “?” 表示 a 可以為空值
fun main(args:Array<String>) {
var a:Array<Int?>? = null
//.......
a=Array(5, {null})
}
全域變數動態陣列
將可空陣列置於函數之外,是希望此陣列可以跨函數共用。但底下紅色部份出現了錯誤。原因是a陣列雖然產生了 5 個空間,但卻可能又被 test() 改成 null,所以紅色部份就會出現 “a可能被其他地方更改” 的錯誤訊息。
var a:Array<Int?>? = null
fun main(args:Array<String>) {
a=Array(5, {null})
test()會因為這一行讓 a 又變成 null
for (i in a.indices){
a[i]=10
}
}
fun test(){
a=null
}
為了解了上述問題,首先必確保 test()不會被執行,然後加上非空斷言 a!!.indices,而在指定元素處,也必需改成 a!!.set(索引, 值),若要取值則改為 a!!.get(索引)。
var a:Array<Int?>? = null
fun main(args:Array<String>) {
a=Array(5, {null})
//test()
for (i in a!!.indices) {
a!!.set(i, 10)
}
}
fun test(){
a=null
}
.all
.all會將陣列裏的元素傳給 {} 區塊進行 and 判定,只要其中一個不符合資料,就回傳false值。若全部都符合,就傳回ture
fun main(args:Array<String>){
var a=arrayOf<String>("5", "15")
var b=a.all{
it.toInt()>10
}
println(b)
}
結果:
false