2012-12-10 12 views
8

स्वीकार करने की अनुमति दे रहा हूं, मैं एक ऐसा फ़ंक्शन लिखने की कोशिश कर रहा हूं जो कुछ तारों को लेता है और उनके साथ कुछ करता है।जावा फ़ंक्शन को संग्रह या सरणी

केवल एक चीज जो मैं करने जा रहा हूं कि तारों का सेट उनके ऊपर लूप है। अभी मैं जो निरर्थक लगता है के बाद से

for(String i : myStrings){ 
    bar(i); 
} 

String [] के प्रकार myStrings के लिए पूरी तरह से वैध कोड होगा

public void foo(String[] myStrings){ 
    foo(java.util.Arrays.asList(myStrings)); 
} 

public void foo(Iterable<String> myStrings){ 
    for(String i : myStrings){ 
     bar(i); 
    } 
} 

की तर्ज पर एक अजीब निर्माण के साथ खत्म।

क्या कोई कक्षा है जिसे मैं foo स्वीकार कर सकता हूं जो संग्रह और सरणी दोनों को अनुमति देगा?

उत्तर

8

देखें Why is an array not assignable to Iterable?

लघु जवाब: नहीं। ऐरे प्रकार सिंथेटिक कोड हैं, जैसा कि मैं इसे समझता हूं, और इस प्रकार Iterable या किसी अन्य प्रकार को लागू नहीं करता है। आपको एक ओवरलोडेड विधि प्रदान करने की आवश्यकता है या कॉल साइट पर Arrays.asList पर कॉल करने के लिए ग्राहकों की आवश्यकता है।

+1

धन्यवाद, मुझे लगता है कि मैं अभी भी जावा को मनाने की कोशिश कर रहा था कि उसके दिल में गहराई यह पाइथन था। – BostonJohn

+1

हाहा, यहां कोई बतख टाइप नहीं है - क्षमा करें। :) –

+1

वर्बोज टाइपिंग की दुनिया में आपका स्वागत है। जावा DRY के बजाय WET के सिद्धांत पर आधारित है (जैसा कि स्वयं को दोहराने के बजाए सबकुछ दो बार लिखें)। – akuhn

3

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

आप केवल Iterable स्वीकार कर सकते हैं, क्योंकि सरणी के चारों ओर गुजरने के रूप में थोड़ा पुराना स्कूल है (ArrayList पर सरणी के प्रदर्शन लाभ नगण्य हैं)। Arrays.asList(T... a) का उपयोग कर एक मौजूदा सरणी को आसानी से लपेटा जा सकता है और List में परिवर्तित किया जा सकता है।

+0

यह एक अच्छी कॉल है। मैं लिखने वाले किसी भी नए कोड में ऐरेलिस्ट का उपयोग करता हूं, लेकिन मेरे पास विरासत में आने वाले कई सारे सरणी हैं। – BostonJohn

1

हालांकि प्रत्येक लूप के लिए सरणी का उपयोग किया जा सकता है, वे Iterable लागू नहीं करते हैं। केवल दो संभावनाएं हैं, या तो आपने जो विधि बताई है उसे अधिभारित करें, या केवल केवल पुनरावर्तनीय संस्करण प्रदान करें और ग्राहक को Arrays.asList() पर कॉल करने के लिए मजबूर करें। ऐसे मामले में

public void foo(String... myStrings){ 
    foo(java.util.Arrays.asList(myStrings)); 
} 

, आदिम सरणियों और आदिम-आवरण सरणियों के बीच असंगति से सावधान:

मामले में आप भी सरणी अधिभार प्रदान करना चाहते हैं, तो आप उसके हस्ताक्षर सरल सरणी से varargs को बदल सकता है:

static void foo(int... ints) {} 
foo(new Integer[] {1, 2}); // compile error 

और:

static void foo(Integer... integers) {} 
foo(new int[] { 1, 2 }); // compile error 

और सबसे अस्पष्ट हिस्सा है, सामान्य varargs साथ:

static <T> T[] foo(T... ts) { 
    return ts; 
} 

आप पूर्णांकों की एक सरणी पार कर लेते हैं: 1 और 2:

Integer[] integers = { 1, 2 }; 
System.out.println(Arrays.deepToString(foo(integers))); 
> [1, 2] 

ts का मूल्य 2 तत्वों के साथ पूर्णांकों की एक सरणी है ।

हालांकि, अगर आप आदिम ints की एक सरणी गुजरती हैं, एक अजीब बात होता है:

int[] ints = { 1, 2 }; 
System.out.println(Arrays.deepToString(foo(ints))); 
> [[1, 2]] 

इस मामले में, ts का मूल्य केवल एक ही तत्व है, साथ पूर्णांक सरणियों की एक सरणी (int[][]) जो मूल रूप से पारित सरणी है। इसका कारण यह है कि intObject नहीं है (ऑटोबॉक्सिंग यहां मदद नहीं करता है), जबकि स्याही की एक सरणी है, इसलिए T प्रकार पैरामीटर का मान int[] बन जाता है।

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