जावा अरैलिस्ट कॉपी


214

मेरा ArrayList l1आकार 10 है। मैं l1नई सूची संदर्भ प्रकार को निर्दिष्ट करता हूं l2। एक ही वस्तु के लिए इच्छा l1और l2बिंदु ArrayList? या ArrayListवस्तु की एक प्रति सौंपी गई है l2?

l2संदर्भ का उपयोग करते समय , यदि मैं सूची ऑब्जेक्ट को अपडेट करता हूं, तो यह l1संदर्भ प्रकार में परिवर्तन को भी दर्शाता है ।

उदाहरण के लिए:

List<Integer> l1 = new ArrayList<Integer>();
for (int i = 1; i <= 10; i++) {
    l1.add(i);
}

List l2 = l1;
l2.clear();

2 सूची ऑब्जेक्ट बनाने और पुराने से नए संग्रह पर कॉपी करने के अलावा, नए संदर्भ चर के लिए किसी सूची ऑब्जेक्ट की प्रतिलिपि असाइन करने का कोई अन्य तरीका नहीं है?

जवाबों:


460

हां, असाइनमेंट सिर्फ (जो एक संदर्भ है) के मान की प्रतिलिपि करेगा । वे दोनों एक ही वस्तु को संदर्भित करेंगे।l1l2

हालांकि एक उथली प्रतिलिपि बनाना बहुत आसान है:

List<Integer> newList = new ArrayList<>(oldList);

(सिर्फ एक उदाहरण के रूप में।)


1
क्या किसी सरणी के केवल एक हिस्से को नई सरणी सूची में कॉपी करना संभव है, कुशलता से। उदाहरण के लिए: स्थिति 5 और 10 के बीच तत्वों को एक सरणी सूची से दूसरे नए सरणी सूची में कॉपी करें। मेरे आवेदन में सीमा बहुत बड़ी होगी।
अश्विन

1
@ अश्विन: वैसे तो यह एक ओ (एन) ऑपरेशन है, लेकिन हां ... आप List.subListमूल सूची के एक खंड पर "दृश्य" प्राप्त करने के लिए उपयोग कर सकते हैं ।
जॉन स्कीट

क्या होगा यदि सरणी सूचियाँ नेस्टेड हैं (ArrayList<ArrayList<Object>>)? क्या यह पुनरावर्ती सभी बच्चों की प्रतियां बना देगा ArrayList ऑब्जेक्ट?
बिल्ली

3
@Cat: नहीं ... यह केवल एक उथली प्रति है।
जॉन स्कीट

1
@ शनिकादिरीवेरा: आप इसे धाराप्रवाह तरीके से धाराओं के साथ कर सकते हैं, हाँ। लेकिन मुश्किल हिस्सा एक गहरी प्रतिलिपि बना रहा है, जो अधिकांश ऑब्जेक्ट प्रदान नहीं करेगा। यदि आपके पास कोई विशिष्ट मामला है, तो मेरा सुझाव है कि आप विवरण के साथ एक नया प्रश्न पूछें।
जॉन स्कीट

67

उपयोग करने का प्रयास करें Collections.copy(destination, source);


14
यह समझाने के लिए कि यह बेहतर क्यों हो सकता है new ArrayList<>(source);?
एलेक्स

6
@ एट्रैक इसकी एक और तरीका है, नए ArrayList के बजाय उथली कॉपी करना () यह एक और एल्गोरिथ्म का उपयोग किया जाता है और किसी भी सूची कार्यान्वयन के लिए इस्तेमाल किया जा सकता है, न कि केवल एक ArrayList के लिए, यह सब है :)
Sergii Zagriicht

14
यह तरीका बहुत ही भ्रामक है! दरअसल, यह वर्णन है। यह कहता है: "एक स्रोत सूची से तत्वों को गंतव्य में कॉपी करता है", लेकिन उनकी नकल नहीं की जाती है! उन्हें संदर्भित किया जाता है इसलिए वस्तुओं की केवल 1 प्रति होगी और यदि वे आपस में मिलती हैं, तो आप परेशानी में हैं
ACV

5
java-api में कहीं भी क्लोनिंग किसी भी संग्रह वर्ग द्वारा नहीं की जाती है
Vikash

यह उत्तर पूरे अर्थों में नहीं आता है। Collections.copyके विकल्प के बिल्कुल नहीं है new ArrayList<>(source)। जो Collections.copyवास्तव में करता है वह मान लेता है कि destination.size()कम से कम जितना बड़ा है source.size(), और फिर set(int,E)विधि का उपयोग करके रेंज इंडेक्स-बाय-इंडेक्स की प्रतिलिपि बनाएँ । विधि गंतव्य पर नए तत्व नहीं जोड़ती है। स्रोत कोड का संदर्भ लें यदि यह Javadoc से पर्याप्त रूप से स्पष्ट नहीं है।
रेडियोडफ

35

हां l1और l2एक ही संदर्भ, एक ही वस्तु की ओर इशारा करेंगे।

यदि आप एक नया ArrayList बनाना चाहते हैं जो अन्य ArrayList के आधार पर आप ऐसा करते हैं:

List<String> l1 = new ArrayList<String>();
l1.add("Hello");
l1.add("World");
List<String> l2 = new ArrayList<String>(l1); //A new arrayList.
l2.add("Everybody");

परिणाम होगा l1अभी भी 2 तत्व l2होंगे और 3 तत्व होंगे।


क्या आप कृपया List<String> l2 = new ArrayList<String>(l1)और के बीच अंतर बता सकते हैं List<String> l2 = l1?
मॉर्टेलमैन

@MortalMan अंतर यह है कि l2 = नया ArrayList <String> (l1) एक पूरी तरह से नई वस्तु है और l2 को संशोधित करना l1 को प्रभावित नहीं करता है, जबकि सूची <string> l2 = l1 आप एक नई वस्तु नहीं बना रहे हैं, लेकिन सिर्फ उसी का संदर्भ दे रहे हैं ऑब्जेक्ट l1 के रूप में, इसलिए इस मामले में l2.add ("एवरीबॉडी"), l1.size () और l2.size () जैसे ऑपरेशन करने से 3 वापस आ जाएंगे क्योंकि दोनों एक ही ऑब्जेक्ट को संदर्भित कर रहे हैं।
अल्फ्रेडो ओसोरियो

19

Arraylist को नष्ट करने के लिए src ArrayList से मूल्यों की नकल करने का एक और सुविधाजनक तरीका इस प्रकार है:

ArrayList<String> src = new ArrayList<String>();
src.add("test string1");
src.add("test string2");
ArrayList<String> dest= new ArrayList<String>();
dest.addAll(src);

यह मूल्यों की वास्तविक प्रतिलिपि है और केवल संदर्भ की प्रतिलिपि नहीं है।


10
मुझे पूरा यकीन नहीं है कि यह सही है। मेरा परीक्षण विपरीत दिखाता है (अभी भी उसी वस्तु को संदर्भित करता है)
invertigo

ArrayAdapter के साथ ArrayList का उपयोग करते समय इस समाधान ने मेरे लिए काम किया
albanx

1
यह उत्तर गलत है। addAll () सिर्फ संदर्भों को कॉपी करता है जैसा कि इन्वर्टिगो ने कहा है। यह कोई गहरी नकल नहीं है।
jk7

एक ArrayList के लिए <स्ट्रिंग> यह उत्तर स्वीकार्य है क्योंकि स्ट्रिंग अपरिवर्तनीय है, लेकिन इसे OP के उदाहरण, एक ArraList <Integer> के साथ आज़माएं, और आप देखेंगे कि यह केवल संदर्भों की प्रतिलिपि बना रहा है।
jk7

बस मेरा दिन नहीं है मुझे लगता है। यह इंटेगर और लॉन्ग जैसी कक्षाएं भी अपरिवर्तनीय हैं, इसलिए हर्षल का जवाब ArrayList <Integer> और ArrayList <String> जैसे सरल मामलों के लिए काम करता है। जहां यह विफल हो जाता है वह जटिल वस्तुओं के लिए है जो अपरिवर्तनीय नहीं हैं।
jk7

8

एक तरीका addAll () है जो एक ArrayList को दूसरे में कॉपी करने के उद्देश्य से काम करेगा।

उदाहरण के लिए आपके पास दो Array Lists हैं: sourceList और targetList , नीचे दिए गए कोड का उपयोग करें।

targetList.addAll (SourceList);


यह भी केवल संदर्भों को कॉपी करता है।
विकाश

4

जावा वस्तुओं को पास नहीं करता है, यह वस्तुओं को संदर्भ (पॉइंटर्स) पास करता है। तो हाँ, l2 और l1 एक ही वस्तु के दो बिंदु हैं।

यदि आपको एक ही सामग्री के साथ दो अलग-अलग सूची की आवश्यकता है, तो आपको एक स्पष्ट प्रतिलिपि बनानी होगी।


3
आप "स्पष्ट प्रति" कैसे बनाते हैं? मुझे लगता है कि आप एक गहरी प्रतिलिपि के बारे में बात कर रहे हैं?
Cin316

1

List.copyOf M अपरिवर्तनीय सूची

तुम ने पूछा था:

क्या सूची की एक प्रति असाइन करने का कोई अन्य तरीका नहीं है

जावा 9 अज्ञात कंक्रीट क्लास के List.ofएक अपरिवर्तनीय बनाने के लिए शाब्दिक का उपयोग करने के तरीके लाया List

LocalDate today = LocalDate.now( ZoneId.of( "Africa/Tunis" ) ) ;
List< LocalDate > dates = List.of( 
    today.minusDays( 1 ) ,  // Yesterday
    today ,                 // Today
    today.plusDays( 1 )     // Tomorrow
);

साथ ही हम भी मिले List.copyOf। यह विधि भी Listअज्ञात ठोस वर्ग का एक अपरिवर्तनीय रिटर्न देती है ।

List< String > colors = new ArrayList<>( 4 ) ;          // Creates a modifiable `List`. 
colors.add ( "AliceBlue" ) ;
colors.add ( "PapayaWhip" ) ;
colors.add ( "Chartreuse" ) ;
colors.add ( "DarkSlateGray" ) ;
List< String > masterColors = List.copyOf( colors ) ;   // Creates an unmodifiable `List`.

"अपरिहार्य" से हमारा तात्पर्य सूची में तत्वों की संख्या से है, और एक तत्व के रूप में प्रत्येक स्लॉट में रखी गई वस्तु संदर्भ निर्धारित है। आप तत्वों को जोड़, गिरा या प्रतिस्थापित नहीं कर सकते। लेकिन प्रत्येक तत्व में रखी गई वस्तु रेफ़रेन्स परस्पर नहीं हो सकती है ।

colors.remove( 2 ) ;          // SUCCEEDS. 
masterColors.remove( 2 ) ;    // FAIL - ERROR.

इस कोड को IdeOne.com पर लाइव देखें ।

date.toString (): [2020-02-02, 2020-02-03, 2020-02-04]

color.toString (): [एलिसब्लू, पपीवाशिप, डार्कस्लेटग्रे]

MasterColors.toString (): [एलिसब्लू, पपीवाशिप, चार्टरेयूज़, डार्कस्लाइगड]

आपने ऑब्जेक्ट संदर्भ के बारे में पूछा। जैसा कि अन्य ने कहा, यदि आप एक सूची बनाते हैं और इसे दो संदर्भ चर (पॉइंटर्स) में असाइन करते हैं, तो आपके पास अभी भी केवल एक सूची है। दोनों एक ही सूची की ओर इशारा करते हैं। यदि आप सूची को संशोधित करने के लिए या तो पॉइंटर का उपयोग करते हैं, तो दोनों संकेत बाद में परिवर्तन देखेंगे, क्योंकि स्मृति में केवल एक सूची है।

इसलिए आपको सूची की एक प्रति बनाने की आवश्यकता है। यदि आप चाहते हैं कि प्रतिलिपि अचूक हो, तो List.copyOfइस उत्तर में चर्चा की गई विधि का उपयोग करें । इस दृष्टिकोण में, आप दो अलग-अलग सूचियों के साथ समाप्त होते हैं, प्रत्येक ऐसे तत्वों के साथ जो एक ही सामग्री ऑब्जेक्ट का संदर्भ रखते हैं। उदाहरण के लिए, Stringरंगों का प्रतिनिधित्व करने के लिए वस्तुओं का उपयोग करने के ऊपर हमारे उदाहरण में , रंग की वस्तुएं कहीं न कहीं स्मृति में तैर रही हैं। दो सूचियाँ एक ही रंग की वस्तुओं की ओर संकेत करती हैं। यहाँ एक चित्र है।

यहां छवि विवरण दर्ज करें

पहली सूची colorsपरिवर्तनीय है। इसका मतलब है कि कुछ तत्वों को ऊपर के कोड में देखा जा सकता है, जहां हमने मूल 3 तत्व Chartreuse(2 = क्रमिक 3 का सूचकांक) को हटा दिया था । और तत्वों को जोड़ा जा सकता है। और तत्वों को कुछ अन्य के लिए इंगित करने के लिए बदला जा सकता है Stringजैसे OliveDrabया CornflowerBlue

इसके विपरीत, चार तत्व masterColorsतय होते हैं। कोई हटाने, कोई जोड़ नहीं, और कोई अन्य रंग प्रतिस्थापित नहीं। यह Listकार्यान्वयन अमोघ है।

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