จะคัดลอกรายการใน Kotlin ได้อย่างไร?
ฉันกำลังใช้
val selectedSeries = mutableListOf<String>()
selectedSeries.addAll(series)
มีวิธีที่ง่ายกว่านี้ไหม
จะคัดลอกรายการใน Kotlin ได้อย่างไร?
ฉันกำลังใช้
val selectedSeries = mutableListOf<String>()
selectedSeries.addAll(series)
มีวิธีที่ง่ายกว่านี้ไหม
คำตอบ:
ใช้งานได้ดี
val selectedSeries = series.toMutableList()
val selectedSeries = series.toList()
ยังใช้งานได้เนื่องจากมีการเรียกtoMutableList()
ใช้งาน
===
และต้องบอกtoList()
ว่าไม่ได้คัดลอกคอลเลกชัน แต่toMutableList()
ทำ
Iterable.toList()
จะส่งคืนemptyList()
ซึ่งจะส่งคืนวัตถุเดียวกัน (ไม่เปลี่ยนรูป) เสมอ ดังนั้นหากคุณทดสอบด้วยemptyList()
คุณจะได้วัตถุเดียวกันกลับมา
toMutableList()
ส่งคืนรายการใหม่ "ส่งคืน MutableList ใหม่ที่เต็มไปด้วยองค์ประกอบทั้งหมดของคอลเล็กชันนี้"
คุณสามารถใช้ได้
รายการ -> toList ()
อาร์เรย์ -> toArray ()
ArrayList -> toArray ()
MutableList -> toMutableList ()
ตัวอย่าง:
val array = arrayListOf("1", "2", "3", "4")
val arrayCopy = array.toArray() // copy array to other array
Log.i("---> array " , array?.count().toString())
Log.i("---> arrayCopy " , arrayCopy?.count().toString())
array.removeAt(0) // remove first item in array
Log.i("---> array after remove" , array?.count().toString())
Log.i("---> arrayCopy after remove" , arrayCopy?.count().toString())
พิมพ์บันทึก:
array: 4
arrayCopy: 4
array after remove: 3
arrayCopy after remove: 4
ฉันสามารถหาทางเลือกได้สองทาง:
1. val selectedSeries = mutableListOf<String>().apply { addAll(series) }
2. val selectedSeries = mutableListOf(*series.toTypedArray())
อัปเดต: ด้วยเอ็นจิ้นการอนุมานประเภทใหม่ (เลือกใช้ใน Kotlin 1.3) เราสามารถละเว้นพารามิเตอร์ประเภททั่วไปในตัวอย่างที่ 1 และมีสิ่งนี้:
1. val selectedSeries = mutableListOf().apply { addAll(series) }
FYI วิธีเลือกใช้ Inference ใหม่kotlinc -Xnew-inference ./SourceCode.kt
สำหรับบรรทัดคำสั่งหรือkotlin { experimental { newInference 'enable'}
สำหรับ Gradle สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการอนุมานประเภทใหม่โปรดดูวิดีโอนี้: KotlinConf 2018 - การอนุมานประเภทใหม่และคุณลักษณะภาษาที่เกี่ยวข้องโดย Svetlana Isakovaโดยเฉพาะอย่างยิ่ง 'การอนุมานสำหรับผู้สร้าง' ที่ 30 '
หากรายการของคุณมีคลาสข้อมูล kotlinคุณสามารถทำได้
selectedSeries = ArrayList(series.map { it.copy() })
คุณสามารถใช้ส่วนขยายที่ให้มาIterable.toMutableList()
ซึ่งจะให้รายชื่อใหม่แก่คุณ น่าเสียดายที่ลายเซ็นและเอกสารแนะนำมีขึ้นเพื่อให้แน่ใจว่า an Iterable
เป็นList
(เช่นเดียวกับtoString
และto<type>
วิธีการอื่น ๆ อีกมากมาย) ไม่มีอะไรรับประกันคุณได้ว่าจะเป็นรายการใหม่ ตัวอย่างเช่นการเพิ่มบรรทัดต่อไปนี้ที่จุดเริ่มต้นของส่วนขยาย: if (this is List) return this
เป็นการปรับปรุงประสิทธิภาพที่ถูกต้อง (หากปรับปรุงประสิทธิภาพได้จริง)
นอกจากนี้เนื่องจากชื่อรหัสผลลัพธ์จึงไม่ชัดเจนนัก
ฉันต้องการเพิ่มส่วนขยายของตัวเองเพื่อให้แน่ใจในผลลัพธ์และสร้างโค้ดที่ชัดเจนมากขึ้น (เช่นเดียวกับที่เรามีสำหรับอาร์เรย์ ):
fun <T> List<T>.copyOf(): List<T> {
val original = this
return mutableListOf<T>().apply { addAll(original) }
}
fun <T> List<T>.mutableCopyOf(): MutableList<T> {
val original = this
return mutableListOf<T>().apply { addAll(original) }
}
ทราบว่าaddAll
เป็นวิธีที่เร็วที่สุดที่จะคัดลอกเพราะใช้ภาษาในการดำเนินการSystem.arraycopy
ArrayList
นอกจากนี้โปรดระวังว่าสิ่งนี้จะทำให้คุณได้สำเนาตื้น ๆเท่านั้น
addAll(this@copyOf)
เพราะthis
ข้างในapply
จะอ้างถึงรายการว่างที่สร้างขึ้นใหม่? อย่างนั้นหรือmutableListOf<T>().also { it.addAll(this) }
?
สำหรับสำเนาตื้นฉันขอแนะนำ
.map{it}
ซึ่งจะใช้ได้กับคอลเลกชันหลายประเภท
Map
s มันรวบรวม แต่เนื่องจากit
เป็น a Map.Entry
และสำเนาตื้นคุณจึงมีรายการเดียวกัน
เช่นเดียวกับใน Java:
รายการ:
val list = mutableListOf("a", "b", "c")
val list2 = ArrayList(list)
แผนที่:
val map = mutableMapOf("a" to 1, "b" to 2, "c" to 3)
val map2 = HashMap(map)
สมมติว่าคุณกำหนดเป้าหมายเป็น JVM (หรือ Android) ฉันไม่แน่ใจว่ามันใช้ได้กับเป้าหมายอื่นเนื่องจากมันต้องอาศัยตัวสร้างสำเนาของ ArrayList และ HashMap
ผมจะใช้วิธีขยาย :toCollection()
val original = listOf("A", "B", "C")
val copy = original.toCollection(mutableListOf())
สิ่งนี้จะสร้างใหม่MutableList
แล้วเพิ่มแต่ละองค์ประกอบของต้นฉบับในรายการที่สร้างขึ้นใหม่
MutableList<String>
สรุปประเภทที่นี่จะเป็น หากคุณไม่ต้องการเปิดเผยความไม่แน่นอนของรายการใหม่นี้คุณสามารถประกาศประเภทอย่างชัดเจนว่าเป็นรายการที่ไม่เปลี่ยนรูปได้:
val copy: List<String> = original.toCollection(mutableListOf())
คุณสามารถใช้ตัวArrayList
สร้าง:ArrayList(list)
สำหรับรายการง่ายๆมีวิธีแก้ไขปัญหาที่ถูกต้องมากมายด้านบน
อย่างไรก็ตามเป็นเพียงรายการตื้น ๆ
ฟังก์ชั่นด้านล่างทำงานสำหรับการใด ๆ 2 ArrayList
มิติ คือในทางปฏิบัติเทียบเท่ากับArrayList
MutableList
ที่น่าสนใจคือมันใช้ไม่ได้เมื่อใช้MutableList
ประเภทโจ่งแจ้ง หากต้องการมิติข้อมูลเพิ่มเติมจำเป็นต้องสร้างฟังก์ชันเพิ่มเติม
fun <T>cloneMatrix(v:ArrayList<ArrayList<T>>):ArrayList<ArrayList<T>>{
var MatrResult = ArrayList<ArrayList<T>>()
for (i in v.indices) MatrResult.add(v[i].clone() as ArrayList<T>)
return MatrResult
}
การสาธิตเมทริกซ์จำนวนเต็ม:
var mat = arrayListOf(arrayListOf<Int>(1,2),arrayListOf<Int>(3,12))
var mat2 = ArrayList<ArrayList<Int>>()
mat2 = cloneMatrix<Int>(mat)
mat2[1][1]=5
println(mat[1][1])
มันแสดงให้เห็น 12
ลองใช้โค้ดด้านล่างเพื่อคัดลอกรายการในKotlin
arrayList2.addAll(arrayList1.filterNotNull())