2013-04-24 11 views
17
int[][] array = new int[][] {...} 
int[][] clone = array.clone(); 

मुझे यह काम करने की उम्मीद है। लेकिन ऐसा नहीं हुआ - यह केवल पहला आयाम क्लोन किया गया, और अगर मैं एक असली क्लोन चाहता था तो मुझे मैन्युअल रूप से अन्य आयाम को क्लोन करना पड़ा और क्लोन करना पड़ा। नोट: सामग्री ठीक से कॉपी की गई थी। लेकिन जब मैं clone[0][1] बदल गया है, यह array[0][1]बहु-आयामी सरणी क्लोनिंग

में परिलक्षित और जब .clone() एक उथले क्लोन प्रदर्शन करने के लिए जाना जाता है, int[][] (कम से कम अगर हम अपने आंतरिक कार्यान्वयन पता नहीं है)

क्यों एक वस्तु की तरह दिखता है क्या वह व्यवहार चुना गया है? int[][] सरणी के पहले आयाम की बजाय किसी सरणी ऑब्जेक्ट का संदर्भ नहीं दे रहा है? और किस परिदृश्य में वांछित व्यवहार केवल पहले आयाम क्लोनिंग है?

उत्तर

8

यह व्यवहार क्यों चुना जाता है?

संगति, सबसे अधिक संभावना है।

जैसा कि आप कहते हैं, int[][] एक सरणी वस्तु का संदर्भ देता है। ऐसा ही होता है कि प्रत्येक सरणी तत्व की सामग्री एक और सरणी है, लेकिन यह सिर्फ एक विवरण है। जावा क्लोन सभी सरणी समान रूप से, और चूंकि तत्व किसी भी प्रकार का हो सकते हैं, इसलिए यह एक गहरी प्रतिलिपि करने की गारंटी नहीं दे सकता है।

इसलिए clone() सरणी के लिए एक उथली प्रतिलिपि करता है, इसलिए केवल पहला आयाम क्लोन किया जाता है।

(सामान्यतः ऐसा प्रतीत नहीं होता है कि एक क्लोन गहरी या उथली प्रतियों का तात्पर्य है या नहीं, इस सवाल के लिए एक "सर्वश्रेष्ठ" या "स्पष्ट" उत्तर है। डेवलपर चाहता है कि प्रत्येक फ़ील्ड का उपयोग कैसे किया जा रहा है एप्लिकेशन द्वारा, इसलिए एक आकार-फिट-सभी दृष्टिकोण में स्वाभाविक रूप से सीमाएं होंगी।)

3

यह व्यवहार प्रदर्शित किया गया है क्योंकि कोई वास्तविक बहु आयामी सरणी नहीं है।

जावा सरणी के सरणी बनाकर कई आयाम प्राप्त करता है। जिसका अर्थ है:

int[][] is actually Array<Array<int>> 

इसलिए क्लोन केवल पहले आयाम की प्रतिलिपि करेगा।

यदि आप 3 आयामी सरणी के साथ प्रयास कर रहे थे, तो आपको तीन बार क्लोन करना होगा।

1

clone विधि एक तथाकथित उथली प्रतिलिपि है (another stackoverflow answer on the clone method देखें), जिसका अर्थ है कि सभी तत्व संदर्भ द्वारा प्रतिलिपि बनाई गई हैं।

क्या आप (भी बुलाया गहरी क्लोनिंग) आप अपने आप को कॉपी कर सकते हैं या तो हर एक सरणी रिकर्सिवली Arrays.copy का उपयोग कर चाहते हैं पाने के लिए, तो हर (उप) सरणी आप पाते हैं एक गहरे क्लोन मिलता है, या this stackoverflow answer on deep cloning की जाँच करेगा।

हैप्पी हैकिंग :-)

1

मैं वास्तव में व्यवहार आपने उल्लेख किया है दोहराने के लिए सक्षम नहीं हूँ। मैं इस मुद्दे के मूल कारण के रूप में उथले प्रतिलिपि का उल्लेख कुछ जवाब देख सकता हूं। अगर मैं गलत हूं, तो मुझे सही करें, उथली प्रतिलिपि का मतलब है कि क्लोनिंग के दौरान किसी वस्तु की प्रतिलिपि के बजाय, हमें संदर्भ की प्रति प्राप्त होगी।एक अच्छा स्पष्टीकरण यहां पाया जा सकता है In Java, what is a shallow copy?

इस मामले में उथली प्रतिलिपि केवल यह सुनिश्चित करेगी कि मूल सरणी में परिवर्तन क्लोन सरणी में दिखाई देते हैं लेकिन कॉपी होने से कुछ भी नहीं रोकेंगे।

int[][] array = new int[][] {{1,2,3},{4,5,6}, {7,8,9}}; 
int[][] clone = array.clone(); 

//Try this to see magic of shallow copy 
//array[2][1]=11; 

for(int i=0;i<array.length;i++) 
    for(int j=0;j<array[i].length;j++) 
     System.out.println("array["+i+"]["+j+"]"+array[i][j]); 

for(int i=0;i<clone.length;i++) 
    for(int j=0;j<clone[i].length;j++) 
     System.out.println("clone["+i+"]["+j+"]"+clone[i][j]); 

मेरे लिए क्लोनिंग पूरी तरह से किया जाता है, दोनों एरे के समान सामग्री होती है। एकमात्र कारण मैं इस मुद्दे को प्राप्त करने के बारे में सोच सकता हूं कि क्लोन सरणी कुछ जानकारी नहीं दिखाएगी कि हमने वास्तव में क्लोनिंग के बाद मूल सरणी को संशोधित किया है (उथले प्रतिलिपि तब खेल में आती है)।

बीटीडब्ल्यू मैंने जावा 1.6 का उपयोग किया, मुझे उम्मीद है कि यह कोई मुद्दा नहीं है।

संपादित करें: अगर हमें समझने की आवश्यकता है कि क्यों वे एक बहुआयामी सरणी की गहरी प्रतिलिपि के बजाय एक उथली प्रतिलिपि है। आइए 2 तथ्यों को देखें

  1. क्लोनिंग करते समय ऑब्जेक्ट्स हमेशा उथले प्रतिलिपि (ऑब्जेक्ट के संदर्भ की प्रति) के रूप में क्लोन हो जाते हैं, केवल मूल प्रकारों को वास्तविक प्रति प्राप्त होती है। In Java, what is a shallow copy?
  2. जावा में एक सरणी वास्तव में एक वस्तु Is an array an object in java

अब 1 और 2 के संयोजन है, हम जानते हैं कि जावा में बहुआयामी सरणी सिर्फ एक वस्तु है, जो अन्य सरणी वस्तुओं के संदर्भ में है है।

कुछ ArrayObj -> {ArrayObj, ArrayObj, ArrayObj} की तरह कुछ;

और क्योंकि हमारे पास ऑब्जेक्ट्स (रचना) के अंदर ऑब्जेक्ट्स हैं, तो हमें जावा क्लोनिंग नियम के अनुसार एक उथली प्रति प्राप्त करना होगा।

+0

मैं स्पष्ट करूंगा। क्लोनिंग वास्तव में खुश है, लेकिन यह गहरा नहीं है। – Bozho

संबंधित मुद्दे