2011-02-03 11 views
12

यदि मुझे आवश्यकता हो तो मैं अधिक कोड पोस्ट कर सकता हूं, लेकिन इससे पहले मैं निम्नलिखित विधि के बारे में एक सामान्य प्रश्न पूछना चाहता हूं जिसमें एक सरणी पारित की जाती है, और फिर किसी अन्य सरणी पर सेट की जाती है, लेकिन किसी कारण से मूल सरणी, एक में पारित किया जा रहा है, यह भी बदल रहा है, यह कैसे संभव है/मुझे क्या करना चाहिए? धन्यवादजावा में संदर्भ द्वारा एरे पारित होने लगते हैं, यह कैसे संभव है?

tempBoard currentState के रूप में एक ही आकार की एक सरणी है, और अस्थायी [k] परिवर्तन है कि movePiece में किए जा रहे, वर्तमान स्थिति विधि में घोषित किया जाता है शामिल हैं और एक वैश्विक चर

private int[][] MiniMaxBaseCase(int[][] currentState, int currentColor) 
{ 
    tempBoard = movePiece(currentState,temp[k]); 
} 

private int[][] movePiece(int[][] currentState, int[] move) 
{ 
    if(move[0] == -1) 
     return currentState; 

    //if the piece is just moving 
    if(move[4] == -1) 
    { 
     currentState[move[2]][move[3]] = currentState[move[0]][move[1]]; 
     currentState[move[0]][move[1]] = 0; 
     return currentState; 
    } 

    //if the piece is jumping another 
    if(move[4] != -1) 
    { 
     currentState[move[4]][move[5]] = currentState[move[0]][move[1]]; 
     currentState[move[2]][move[3]] = 0; 
     currentState[move[0]][move[1]] = 0; 
     return currentState; 
    } 

    return currentState; 
} 
+0

Arrays ऑब्जेक्ट्स हैं। ऑब्जेक्ट संदर्भ प्रकार हैं। वहां कोई आश्चर्य नहीं है। – BoltClock

+0

हर जगह के अनुसार मैंने देखा है कि जावा में संदर्भ से गुजरना संभव नहीं है, हालांकि, मूल्य के आधार पर ऑब्जेक्ट संदर्भों को पार करना संभव है। इनके बीच क्या अंतर है। – jbernie2

+0

जॉन की वेबसाइट मेरे लिए नीचे प्रतीत होती है, लेकिन यहां कैश लिंक है: http://webcache.googleusercontent.com/search?q=cache:http://www.yoda.arachsys.com/java/passing.html – Jimmy

उत्तर

26
नहीं है

जावा में:

  • विधि तर्क वास्तव में कर रहे पारित कर-दर-मूल्य, लेकिन
  • सभी जावा में ऑब्जेक्ट और सरणी चरसंदर्भ चर हैं।

एक संदर्भ चर जा रहा है पारित कर-दर-मूल्य कि वस्तु या सरणी कि संदर्भ चर द्वारा की ओर इशारा किया है का शुद्ध प्रभाव पारित कर-दर-संदर्भ है।

आपकी सरणी प्रभावी रूप से पास-दर-संदर्भ थी - यह वही सरणी है।

विशेष रूप से currentStateMiniMaxBaseCase में एक सरणी का संदर्भ है - इसका मान सरणी का स्मृति स्थान है। currentStateMiniMaxBaseCasemovePiece पर मूल्य से गुजरता है, इसलिए MiniMaxBaseCase (एक स्मृति स्थान) का मान में पैरामीटर currentState में कॉपी किया गया - संदर्भ मूल्य द्वारा पारित किया गया था। लेकिन अब currentStatemovePieceMiniMaxBaseCase में उसी स्मृति स्थान पर उसी स्मृति स्थान पर इंगित करता है। तो अब दोनों चर दोनों एक ही सरणी को इंगित करते हैं, यानी शुद्ध प्रभाव यह था कि सरणी प्रभावी रूप से पारित संदर्भ से प्रभावी थी।


संपादित करें: प्रतिलिपि बनाई जा रही बहुआयामी सरणियों

कुछ लोगों को सीधे पहली आयाम/सूचकांक में traversing बिना System.arraycopy() या Array.copyOf() उपयोग करने के लिए सुझाव दिया गया है। यह काम नहीं करेगा।

उपयोग इस बजाय:

public static int[][] copyOf(int[][] original) { 
    int[][] copy = new int[original.length][]; 
    for (int i = 0; i < original.length; i++) { 
     copy[i] = Arrays.copyOf(original[i]); 
    } 
    return copy; 
} 

कारण एक सीधा कॉपी काम नहीं करेगा क्योंकि जावा में, एक 2-आयामी सरणी वास्तव में का एक संग्रह करने के लिए संकेत/संदर्भ की एक सरणी है (बिखरे हुए) 1 -डिमेंशनल सरणी, यानी, int[][]int[] के समूह (बिखरे हुए) के पॉइंटर्स की एक सरणी है। सीधे शब्दों में बस बिखरे हुए int[] सरणियों, की ओर इशारा कॉपी करेंगे 2-डी सरणी पर एक System.arraycopy() या Arrays.copyOf() कर अर्थात इस उथले प्रतिलिपि समाप्त होता है सरणियों की अंतर्निहित सेट साझा करने।ऊपर दिए गए कोड में दिखाए गए अनुसार आपको एक गहरी प्रतिलिपि करनी होगी।

कुछ संदर्भों:

How do I do a deep copy of a 2d array in Java?

हाँ, तुम पर 2 डी बूलियन सरणी गहरी यह नकल करने के क्रम में पुनरावृति करना चाहिए।

http://www.cs.dartmouth.edu/~spl/Academic/Java/JFAQs.html
मैं कैसे बहु-आयामी सरणियों नकल करते हैं?

... जो दो आयामी सरणी प्रतिलिपि बनाई जा रही है लेकिन अधिक problematical क्योंकि बहुआयामी सरणियों सरणियों के सरणियों के रूप में प्रतिनिधित्व कर रहे हैं। यह एक मुद्दा है जब आप एक सरणी क्लोन कर रहे हैं। System.arraycopy() आपको एम्बेडेड सरणी के संदर्भों की प्रतिलिपि देगा। ...

+0

तो मैं क्या कर सकता हूं ताकि यह मूल को बदल न सके? – jbernie2

+1

वही बात जो आप ऑब्जेक्ट रेफरेंस पर करेंगे - जिसका ऑब्जेक्ट आप स्पर्श नहीं करना चाहते हैं: ऑब्जेक्ट को पहले क्लोन करें। – Santa

+1

@ jbernie2 इसे कॉपी करें। –

2

इस बारे में अच्छी पढ़ाई करने के लिए कुछ समय लें।

http://www.cs.toronto.edu/~dianeh/tutorials/params/

"पासिंग सरणी"

सरणी संदर्भ हैं करने के लिए नीचे जाएं। इसका मतलब है कि जब हम पैरामीटर के रूप में सरणी पास करते हैं, तो हम इसके हैंडल या संदर्भ को पार कर रहे हैं। इसलिए, हम विधि के अंदर सरणी की सामग्री को बदल सकते हैं।

यह "148: कंप्यूटर साइंस का परिचय" पाठ्यक्रम से है, जो जावा भाषा पर पहले 2 पाठों के आसपास फिट होना चाहिए।

एक समारोह के लिए एक सरणी की एक प्रति भेजने के लिए, जावा 1.6 में, आप Array.copyOf उपयोग कर सकते हैं, उदाहरण के लिए:

tempBoard = movePiece(Arrays.copyOf(currentState, currentState.length), temp[k]); 

नोट:Array.copyOf पुरातन की एकल आयाम सरणी के लिए ही अच्छा है। किसी और चीज पर प्रयुक्त, यह आपको सभी तत्वों के साथ एक स्वतंत्र सरणी देता है और मूल सरणी को इंगित करता है, चाहे वह ऑब्जेक्ट्स या नेस्टेड सरणी हों।

+0

मेरा मानना ​​है कि यह 'copyOf' 2-डी सरणी की एक उथली प्रतिलिपि करेगा और * नहीं * सरणी की एक वास्तविक गहरी प्रतिलिपि बनाएँ जो मूल सरणी से पूरी तरह से स्वतंत्र है। –

+0

@BertF: किसी संदर्भ प्रकार की एक सरणी उसमें निहित वस्तुओं की * पहचान *, साथ ही उनके राज्य के उनके * अपरिवर्तनीय * पहलुओं को समाहित करती है, लेकिन उनके राज्य * के किसी भी * परिवर्तनीय पहलुओं को समाहित नहीं करती है। एक सरणी जिसमें ऑब्जेक्ट्स के संदर्भ होते हैं जिनके उत्परिवर्तनीय राज्य स्रोत स्रोत में संबंधित सदस्यों के लिए प्रारंभ किए जाते हैं, वास्तव में स्रोत सरणी की एक प्रति नहीं है, लेकिन पूरी तरह से कुछ और है। – supercat

7

जावा में पास-दर-संदर्भ के रूप में ऐसी कोई चीज नहीं है। आपको यह पता चल रहा है और आश्चर्य है कि यह अभी भी ऐसा क्यों लगता है ...

वैसे समस्या यह है कि सरणी ऑब्जेक्ट्स हैं। और ऑब्जेक्ट्स वास्तव में पॉइंटर्स हैं। तो आपको सरणी में पॉइंटर की एक कॉपी मिलती है, लेकिन यह अभी भी सरणी है जो यह इंगित कर रही है।

सिस्टम.एरेकॉपी() का उपयोग करें यदि आप इसमें कोई भी बदलाव करने से पहले सरणी की एक प्रति बनाना चाहते हैं।

+2

आप 2-डी सरणी पर 'System.arraycopy()' का उपयोग करने के बारे में सावधान रहना चाहेंगे - बेवकूफ रूप से उपयोग किया जाता है, आप एक उथली प्रतिलिपि के साथ समाप्त हो जाएंगे जो मूल सरणी की एक स्वतंत्र प्रति नहीं है। –

+1

@ बर्ट: अच्छा बिंदु – yankee

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

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