2009-02-18 13 views
7

मैंने अक्सर सोचा है कि एरेज़, Arrays और ArrayUtils जैसे सहायक वर्गों पर भरोसा करने के बजाय अपने स्वयं के तरीकों के साथ उचित वस्तुओं के रूप में सरणी के उपयोग की अनुमति देना एक अच्छा विचार होगा।क्या जावा ऑब्जेक्ट ऑब्जेक्ट्स के रूप में व्यवहार करना चाहिए?

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

ints.sort();     // Arrays.sort(ints); 
int[] onemore = ints.add(8); // int[] onemore = ArrayUtils.add(ints, 8); 

मुझे यकीन है कि मैं इस विचार के साथ पहले नहीं कर रहा हूँ हूँ, लेकिन मैं मुसीबत जो दूसरों को इस बारे में पहले लिखा है के लिए खोज की है। क्या कोई इस विषय पर कुछ संदर्भों के साथ मेरी मदद कर सकता है?

क्या यह एक अच्छा या बुरा विचार माना जाता है, और क्यों?

इसे कार्यान्वित करना कितना आसान होगा?

कुछ अन्य उदाहरण शामिल हो सकता है (लेकिन उन पर लटका दिया हो, वे सवाल ही बाहरी कर रहे हैं):

int[] ints = {5,4,3,2,1}; 

// Arrays.sort (ints); 
ints.sort(); 

// int pos = Arrays.asList(ints).indexOf (5); 
// int pos = ArraysUtils.indexOf (ints, 5); 
int pos = ints.indexOf (5); 

// Arrays.reverse (ints); 
ints.reverse(); 

Array<Integer> array = ints; // cast to super class. 

// int length = Array.getLength (array); 
int length = array.getLength(); 

// Object n = Array.get (array, 3); 
Object n = array.get (3); 

// Array.set (array, 3, 7); 
array.set (3, 7); 

Object obj = array; 
// if (obj instanceof int[]) 
//  System.out.println(Array.toString((int[]) obj)); 
// else if (....) 
System.out.println (obj); 
+0

महान प्रश्न! :) –

+0

यकीन नहीं है कि आप वहां मिकी ले रहे हैं, बिल :-) यह किसी के सवाल का पुन: पोस्ट है क्योंकि मैंने इसे लिखा होगा, आशा है कि उन्हें शिक्षित किया जाए।यही कारण है कि मैंने इसे विकी किया - मेरे लिए कोई दोहराव नहीं। – paxdiablo

+0

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

उत्तर

7

सरणी एक अच्छे कारण के लिए जावा में कक्षाएं नहीं हैं - वे के नक्शे लोगों की समझ पर अच्छी तरह से सी-शैली भाषाओं के साथ अनुभव से एक सरणी कैसे काम करनी चाहिए। वस्तुओं के बजाए सरणी निम्न-स्तर वाले कंटेनर बनाने के प्रदर्शन कारण भी हैं। इस वजह से, कभी-कभी संग्रह के बजाय एक आदिम सरणी का उपयोग करने के लिए प्रदर्शन लाभ होते हैं।

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

+1

मैं मानता हूं कि '95 में आदिम भावनाओं जैसे सरणी का इलाज करना, हालांकि मुझे लगता है कि यह एक और ऑब्जेक्ट उन्मुख दृष्टिकोण के लिए समय है। ऑटो-मुक्केबाजी/अन-मुक्केबाजी की तरह यह पहले से ही संलग्नक के साथ सरणी के लिए उपलब्ध कार्यों का इलाज करता है। –

+2

Arrays primitives नहीं हैं। Class.isPrimitive के लिए दस्तावेज़ पढ़ें। –

+0

'ऑब्जेक्ट-ओरिएंटेशन' हमेशा पीटर की अच्छी बात नहीं है! –

1

यह बीएडी विचार नहीं है। चीज यह संग्रह पर पहले से ही किया जा चुका है। यदि आप पागल हो जाना चाहते हैं तो ArrayList को विस्तारित करने का प्रयास करें।

+0

क्या एरेलेलिस्ट की कमी प्राइमेटिव्स के लिए कुशल समर्थन है, [] ऑपरेटर, दो ऑब्जेक्ट बनाता है (द ArrayList और ऑब्जेक्ट []) जब आपको केवल एक की आवश्यकता होती है। –

3

हां। लेकिन मेरी राय है कि जावा में पर कोई प्राइमेटिव नहीं होना चाहिए। मुझे लगता है कि जावा में प्राइमेटिव भाषा की शुद्धता से एक ब्रेक हैं। जावा में सबकुछ वस्तुओं होना चाहिए। या नहीं, वस्तुओं ढेर या ढेर पर आवंटित किए जाते हैं JVM नहीं एक भाषा निर्माण के कार्यान्वयन विस्तार होना चाहिए। लेकिन मुझे लगता है कि मेरी राय अधिक से अधिक कट्टरपंथी हो सकती है।

ऑटोबॉक्सिंग से पहले, प्राइमेटिव्स और ऑब्जेक्ट्स से निपटना बहुत बोझिल था।

तो सरणियों वस्तुओं थे और autoboxed जा सकता है (और generisized!), हम

Array<Integer> myArray = new Integer[]; 
myArray.add(8); 
int x = myArray[0]; 
.... 

या

Array<Class<? extends MyBaseObject>> myArray = {ExtendedObject.class} 
ExtendedObject object = myArray[0].newInstance(); 
.... 
+0

मैं मानता हूं कि प्राइमेटिव जिन्हें पारदर्शी रूप से ऑब्जेक्ट्स के रूप में नहीं माना जा सकता है, दुर्भाग्यपूर्ण है। कंपाइलर/जेवीएम इसे काम करने में सक्षम होना चाहिए। ArrayUtils के पास दो तरीकों से ऑब्जेक्ट() और torimrimitive() है। सरणी के प्रकार को बदलने के लिए इसमें एक और तरीका हो सकता है। –

+0

मैं सुझाव दूंगा कि ऐरे और इंटीजर [] एक ही चीज़ लिखने के दो तरीके होंगे। ;) –

+0

जावा में इन तरह की चीजों को ठीक करने में बहुत देर हो चुकी है। उन भाषाओं पर नज़र डालें जिनमें वे शुरुआत के बाद से डिजाइन का हिस्सा हैं। उदाहरण के लिए स्कैला में सबकुछ एक वस्तु है। –

5

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

एक के लिए, जैसा कि अन्य ने इंगित किया है, संग्रह कक्षाएं आपके लिए यह करती हैं। दूसरे के लिए, myarray.sort() इतना अच्छा नहीं है क्योंकि आप ऑब्जेक्ट्स के सरणी बना सकते हैं जिसके लिए सॉर्टिंग को परिभाषित नहीं किया गया है। मान लीजिए मेरे पास

Foo[] foos; 

और Foo तुलनात्मक नहीं है। Foos.sort() पर क्या होता है?हम निश्चित रूप से यह केवल पुरातन

int[] ints; 
ints.sort(); //legal 
Object[] objects; 
objects.sort(); //illegal 

के लिए काम करते हैं और आप निश्चित रूप से नहीं कर सकता संकलक केवल तुलनीय वस्तुओं के लिए वाक्य रचना के लिए अनुमति देने के लिए नहीं करना चाहते। और एक बार जब आप

myarray.add(new Foo()); 

यह बिंदुहीन है, क्योंकि जावा में सरणी बढ़ने योग्य नहीं हैं।

यह अगर प्रिंट एक सरणी आपको लगता है कि बेकार

([I'm an array(*&(* 

बकवास है, हालांकि हार नहीं मानी अच्छा होगा।

+0

ArrayUtils.add(), addAll() और निकालें() तत्व जोड़ा गया एक नया सरणी देता है। –

+0

जब आप ArrayList के ऊपर नहीं जाना चाहते हैं तो ये विधियां सरणी के प्रबंधन के लिए बहुत उपयोगी होती हैं। –

0

उन लोगों के लिए जो पिछली पोस्ट को बंद कर चुके थे। कुछ अन्य उदाहरणों में

int[] ints = {5,4,3,2,1}; 
ints.sort(); // instead of Arrays.sort(ints); 
int pos = ints.indexOf(5); // instead of Arrays.asList(ints).indexOf(5); or ArraysUtils.indexOf(ints, 5); 
ints.reverse(); // instead of Arrays.reverse(ints); 
Array<Integer> array = ints; // cast to super class. 
int length = array.getLength(); // instead of Array.getLength(array); 
Object n = array.get(3); // instead of Array.get(array, 3); 
array.set(3, 7); // instead of Array.set(array, 3, 7); 
Object obj = array; 
System.out.println(obj); // prints [5,4,7,2,1] instead of having to 
// if (obj instanceof int[]) System.out.println(Array.toString((int[]) obj)); else if (....) 

int[] ints2 = ints.copyOf(2); 
int[] ints3 = ints.subArray(2,4); 
ints.sort(myComparator); 
List<Integer> list = ints.asList(); 
Set<Integer> set = ints.asSet(); 
long total = ints.sum(); 
double avg = int.average(); 
int max = ints.max(); 
int max2 = ints.max(myComparator); 
http://commons.apache.org/lang/api/org/apache/commons/lang/ArrayUtils.html 
int[] onemore = ints.add(8); // instead of ArrayUtils.add(ints, 8); 
int[] moreInts = ints.addAll(ints2); // instead of ArraysUtils.addAll(ints, ints2); 
int[] oneless = int.remove(3); // instead of ArrayUtils.remove(ints, 3); 
Integer[] integers = int.toObject(); 
int[] intsAgain = integers.toPrimitive(); 
+0

मैं इस सवाल को एक परिशिष्ट, पीटर के रूप में कॉपी करूंगा। – paxdiablo

2

मुझे जवाब देने से पहले, मैं आपको इस मुद्दे की स्थिति बता दूंगा।

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

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

सरणियों के लिए केवल वास्तविक इंटरफ़ेस System.arrayCopy स्थिर विधि या सरणी स्थिर तरीकों, जो सबसे अधिक कुशलता से सरणियों से/कॉपी कर सकते हैं। *।

SHOULD के जवाब में; यह हल हो गया है, हालांकि एक मानक उत्तर से बेहतर होगा: ArrayList का उपयोग करें।

+0

Arrays केवल क्लोन() विधि को लागू करते हैं, अन्य सभी विधियों को ऑब्जेक्ट से विरासत में मिलाया जाता है। ऐसा नहीं है कि वे लागू/उपलब्ध नहीं हैं। वो हैं। उन सभी को। –

2

हाँ, मुझे विश्वास है कि सरणियों एक API ही भाषा में निर्दिष्ट एक से परे परिभाषित होनी चाहिए। विशेष रूप से, यह परेशान है कि Foo[]Iterable<Foo> लागू नहीं करता है। हां, मुझे पता है कि इसे लपेटना आसान है - लेकिन यह आपको परेशान करना है।

.NET यह अधिकतर सही हो जाता है, Array प्रकार जो ज्यादातर गैर-सामान्य पहुंच के लिए होता है, और विभिन्न सामान्य इंटरफेस जिन्हें वास्तविक सरणी द्वारा लागू किया जाता है। उदाहरण के लिए:

IList<int> intList = new int[10]; 

(यह मदद करता है जो .NET जेनरिक आदिम प्रकार से निपटने के बेहतर जावा करता है।)

केवल कमियां मैं इस दृष्टिकोण का देखा है है कि सरणियों .NET में covariant किया जा सकता है , लेकिन सामान्य जेनेरिक नहीं हैं, और यह चीजें गैर-शून्य-आधारित सरणी और आयताकार सरणी के साथ थोड़ा उलझन में आती हैं।

एक तरफ, विभिन्न लोगों ने इस धागे में प्राइमेटिव के रूप में सरणी को संदर्भित किया है। जबकि वे निश्चित रूप से विशेष हैंडलिंग करते हैं, वे प्राइमेटिव होने के लिए परिभाषित नहीं हैं। language spec, section 4.2 से:

एक आदिम प्रकार जावा प्रोग्रामिंग भाषा द्वारा पूर्वनिर्धारित और उसके आरक्षित कीवर्ड (§3 द्वारा नाम पर है।9):

 
PrimitiveType: 
     NumericType 
     boolean 

NumericType: 
     IntegralType 
     FloatingPointType 

IntegralType: one of 
     byte short int long char 

FloatingPointType: one of 
     float double 
1

मेरा मानना ​​है कि यह कई स्तरों पर अनुकूलता को तोड़ने के बिना लागू करने के लिए बहुत कठिन है।

  • जेवीएम अन्य वस्तुओं की तुलना में सरणी थोड़ा अलग तरीके से व्यवहार करता है। निर्माण/प्रारंभिकता अलग है: एक चीज़ के लिए कोई कन्स्ट्रक्टर नहीं कहा जाता है। आप नई विधियों को कैसे जोड़ना चाहते हैं? यदि सुपरक्लास जोड़कर, क्या आप इसके कन्स्ट्रक्टर को कॉल करेंगे?
  • Arrays रनटाइम में तत्व के प्रकार को जानते हैं, जेनेरिक नहीं करते हैं। यदि आप सभी सरणी के लिए नया सुपरक्लास जोड़ना चाहते हैं (जैसे आपने मूल प्रश्न में सुझाव दिया है), तो क्या आप इसे सामान्य बना देंगे? यह भी ध्यान रखें कि जावा में सरणी कॉन्वर्सेंट हैं, जेनेरिक नहीं हैं।
  • सरणी जावा भाषा विशिष्टता में निर्दिष्ट तरीकों/क्षेत्रों के सेट तय कर दी है (वस्तुओं से सभी तरीकों, जो स्पष्ट रूप JLS, लंबाई क्षेत्र में नाम हैं)। इस पर निर्भर करते हुए नए सदस्यों को जोड़ने से मौजूदा ग्राहकों को तोड़ने की संभावना है। (यानी सरणियों अपने यादृच्छिक वर्ग नहीं हैं)
  • सरणी क्रमबद्धता शायद बहुत प्रभावित होगा
  • मुझे यकीन है कि अधिक कार्यान्वयन विवरण जो इस नए तरीके के साथ काम करने बनाना होगा extremly मुश्किल :-(
  • कार्यक्रम संकलित देखते हैं हूँ होगा पुराने JVMs पर काम नहीं। क्या बदतर है, क्रियान्वयन के आधार पर वर्ष JVMs के लिए संकलित प्रोग्राम्स नई JVMs पर संशोधित सरणियों के साथ काम नहीं कर सकता।

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

1

मुझे व्यक्तिगत रूप से ऑब्जेक्ट होने का विचार पसंद है, और उदाहरण के लिए, यह पहले से ही छोटे-छोटे में किया जा चुका है। हालांकि, सब कुछ बनाने के परिणाम, यहां तक ​​कि विधियों/funcitons भी एक वस्तु बहुत दूर तक पहुंचने के लिए हैं (मुझे क्या मतलब है देखने के लिए smalltalk पर एक नज़र डालें)। "सब कुछ एक वस्तु है" के आवेदन में सुसंगत होने के परिणामस्वरूप - एक ऐसी भाषा में परिणाम जो सी (या जावा) जैसी कुछ भी नहीं दिखता है।

जावा बहुत सी जानबूझकर सी प्रोग्रामर के लिए पहुंचने के लिए डिज़ाइन किया गया था, और यह उस पर सफल रहा है, लेकिन यह वास्तव में छोटे-छोटे की तुलना में बहुत ऑब्जेक्ट उन्मुख नहीं है। यह विरासत एक सी प्रकार के रूप में पूरे स्थान पर दिखाई देती है, जैसे कि सरणी और तथ्य यह है कि प्राइमेटिव हैं।

तो SHOULD के प्रश्न का उत्तर देने के लिए, मैं नहीं कहूंगा, क्योंकि जावा उस परिवर्तन के साथ जावा नहीं होगा। जैसा कि अन्य ने इंगित किया है, ऐसे अन्य वर्ग हैं जो आपको जावा में ऑब्जेक्ट्स का उपयोग करके सी में सरणी के साथ किए गए कार्यों को संभालने देते हैं, लेकिन आदिम डेटा प्रकारों और सरणी से छुटकारा पाने के लिए एक अलग भाषा के लिए एक कार्य बेहतर छोड़ दिया जाता है , IMHO।

0

एक कारण मेरा मानना ​​है कि यह बहुत कठिन नहीं होगा कि आप परोक्ष रूप से वस्तु को संशोधित करके विधियां जोड़ सकते हैं (मैं मानता हूँ एक असली हैक, लेकिन यह यह काम करता है पता चलता) तरीकों को जोड़ कर वस्तु के लिए, निम्नलिखित कोड है

int[] ints = {5, 4, 3, 2, 1}; 
System.out.println("ints= "+ints); 
ints.sort(); 
System.out.println("after sort() ints= "+ints); 
ints = ints.add(6); 
System.out.println("after add(6) ints= "+ints); 

प्रिंटों

ints= [5, 4, 3, 2, 1] 
after sort() ints= [1, 2, 3, 4, 5] 
after add(6) ints= [1, 2, 3, 4, 5, 6] 

यह जावा 5 & 6 और दोनों संकलक और आईडीई के साथ काम करता है इस संभाला के रूप में मैं उम्मीद थी।

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

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