कोटलिन में किसी सूची को क्लोन या कॉपी कैसे करें


105

कोटलिन में सूची की प्रतिलिपि कैसे करें?

मैं उपयोग कर रहा हूँ

val selectedSeries = mutableListOf<String>()
selectedSeries.addAll(series)

क्या कोई आसान तरीका है?


1
मुझे लगता है कि आपका समाधान पहले से ही सबसे आसान तरीका है, अगर आपको गहरी क्लोनिंग की आवश्यकता नहीं है।
सेरदार समैंसिओलू

जवाबों:


145

यह ठीक काम करता है।

val selectedSeries = series.toMutableList()

6
val selectedSeries = series.toList()यह भी काम करता है क्योंकि यह toMutableList()इसके कार्यान्वयन में कहता है।
फ्लेवियो फारिया

4
@ FlávioFaria ने इसे अभी परीक्षण किया है ===और कहना toList()है कि संग्रह को कॉपी नहीं करता है, लेकिन toMutableList()करता है
पेपरमिंट धान

3
@PeppermintPaddy यह करता प्रतिलिपि, खाली सूचियों के मामले को छोड़कर। यदि स्रोत खाली है, तो Iterable.toList()रिटर्न emptyList(), जो हमेशा एक ही (अपरिवर्तनीय) वस्तु देता है। इसलिए यदि आप परीक्षण करते हैं emptyList()तो आपको वही वस्तु वापस मिल जाएगी।
लॉरेंस गोंसाल्वेस

4
यह एक अच्छा जवाब नहीं है, और निश्चित रूप से सही नहीं है, कोई गारंटी नहीं है कि भविष्य के कार्यान्वयन में बदलाव हो सकता है, जब तक कि इसके विशेष रूप से प्रलेखित नहीं किया जाता है कि यह विधि कॉल हमेशा एक नई प्रतिलिपि लौटाएगा।
भार्गव

@BrunoJCM, अब ऐसा नहीं है। कोटलिन डॉक्स राज्य जो toMutableList()एक नई सूची देता है , "इस संग्रह के सभी तत्वों से भरा एक नया MutableList देता है।"
पीर निल्स एम्सन

23

आप उपयोग कर सकते हैं

सूची -> सूची ()

ऐरे -> ऐरे ()

ArrayList -> toArray ()

म्यूटेबलिस्ट -> म्यूटेबलिस्ट ()


उदाहरण:

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

15

मैं दो वैकल्पिक तरीकों से आ सकता हूं:

1. val selectedSeries = mutableListOf<String>().apply { addAll(series) }

2. val selectedSeries = mutableListOf(*series.toTypedArray())

अद्यतन: नए प्रकार के आविष्कार इंजन (कोटलिन 1.3 में ऑप्ट) के साथ, हम जेनेरिक प्रकार के पैरामीटर को 1 उदाहरण में छोड़ सकते हैं और यह है:

1. val selectedSeries = mutableListOf().apply { addAll(series) }

FYI करें। नए इंट्रेंस में ऑप्ट-इन करने का तरीका kotlinc -Xnew-inference ./SourceCode.ktकमांड लाइन के लिए है, या kotlin { experimental { newInference 'enable'}ग्रैडल के लिए है। नए प्रकार के आविष्कार के बारे में अधिक जानकारी के लिए, इस वीडियो को देखें: KotlinConf 2018 - स्वेतलाना इसकोवा द्वारा नए प्रकार के इंजेक्शन और संबंधित भाषा की विशेषताएं , विशेष रूप से 'बिल्डरों के लिए इंजेक्शन ' 30 पर '


2 जवाबों में विभाजित किया जाना चाहिए, क्योंकि मुझे लगता है कि पहला सही है, लेकिन बाद में कुछ सुंदरता का अभाव है।
होलगर ब्रैंडल

@ जैकोब वू: मैं यह देखकर हैरान था कि दूसरे समाधान में * प्रतीक एक त्रुटि पैदा नहीं करता था। यह क्या करता है? मैंने "यूनीरी गुणा" के साथ एक खोज की, लेकिन कुछ भी नहीं मिला।
लैंसफ्लरे

1
@Lensflare * का अर्थ है एक सरणी को अलग-अलग वस्तुओं में बदलना, जैसे कि mutableListOf (* [1, 2, 3]) का अर्थ है mutableListOf (1, 2, 3), यह vararg के विपरीत संचालन की तरह है
याकूब वू

1
@ जैकोब वू: धन्यवाद। आपके उत्तर से मुझे पता चल गया कि ऑपरेटर को "स्प्रेड ऑपरेटर" कहा जाता है। मैं देखता हूं कि एक सरणी के साथ कुछ मापदंडों को एक varargs सूची में मिलाकर यह कैसे मदद करता है। लेकिन आपके उदाहरण में इसका क्या लाभ है? यह तेज है या कुछ और है? या यह सुनिश्चित करने की कुंजी है कि संग्रह की प्रतिलिपि बनाई गई है?
लेन्सफ्लरे

@ लेंसलारे मुझे लगता है कि लाभ सिंटैक्स है - कोड छोटा है, और कोई स्पष्ट सामान्य प्रकार की आवश्यकता नहीं है (जैसे मेरे पहले उदाहरण में)। दृश्य के पीछे, मेरा मानना ​​है कि कोड को सरणी संचालन के लिए संकलित किया गया है, इसलिए प्रदर्शन समान होना चाहिए।
जैकब वू


9

आप दिए गए एक्सटेंशन का उपयोग कर सकते हैं Iterable.toMutableList()जो आपको एक नई सूची प्रदान करेगा। दुर्भाग्य से, जैसा कि इसके हस्ताक्षर और प्रलेखन का सुझाव है, यह सुनिश्चित करने के लिए है कि 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) }?
फ्रेंको लियोन तोकाली

5

उथली प्रति के लिए, मैं सुझाव देता हूं

.map{it}

यह कई संग्रह प्रकारों के लिए काम करेगा।


1
ध्यान दें कि यह काम नहीं करता है Map। यह संकलित करता है, लेकिन चूंकि ita है Map.Entry, और प्रति उथली है, तो आपके पास समान प्रविष्टियां हैं।
noamtm

1
@noamtm हाँ, यह वही है जिसका मेरा मतलब उथली नकल से है। यह विधि कभी भी प्रविष्टियों की नकल नहीं करेगी। यह केवल समान प्रविष्टियों के साथ संग्रह की एक प्रति बनाएगा। नक्शा यहां कुछ खास नहीं है।
लेन्सफ्लारे

2
मेरा कहना यह है कि, भले ही यह नक्शे पर भी इसका उपयोग करने के लिए आकर्षक है, और यह काम करता है और लगता है - यह वास्तव में काम नहीं करता है।
noamtm

4

जैसे जावा में:

सूची:

    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 के कॉपी कंस्ट्रक्टर्स पर निर्भर करता है।


2

मैं का प्रयोग करेंगे विस्तार विधि :toCollection()

val original = listOf("A", "B", "C")
val copy = original.toCollection(mutableListOf())

यह एक नया बना देगा MutableListऔर फिर मूल के प्रत्येक तत्व को नव-निर्मित सूची में जोड़ देगा।

यहाँ अनुमान प्रकार होगा MutableList<String>। यदि आप इस नई सूची की परिवर्तनशीलता को उजागर नहीं करना चाहते हैं, तो आप स्पष्ट रूप से एक अपरिवर्तनीय सूची के रूप में घोषित कर सकते हैं:

val copy: List<String> = original.toCollection(mutableListOf())

0

सरल सूचियों के लिए ऊपर कई सही समाधान हैं।

हालाँकि, यह केवल उथले सूचियों के लिए है।

नीचे दिया गया फ़ंक्शन किसी भी 2 आयामी के लिए काम करता है ArrayListArrayListव्यवहार में, के बराबर है 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



-1

कोटलिन में सूची की प्रतिलिपि बनाने के लिए नीचे दिए गए कोड का प्रयास करें

arrayList2.addAll(arrayList1.filterNotNull())
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.