2011-07-19 10 views
23

मैं सरणी रूप में एक Iterable की सामग्री को वापस करने के लिए एक सामान्य विधि लिखने की कोशिश कर रहा हूँ।टी [] में Iterable <T> बदलने के लिए पुन: प्रयोज्य विधि?

public class IterableHelp 
{ 
    public <T> T[] toArray(Iterable<T> elements) 
    { 
     ArrayList<T> arrayElements = new ArrayList<T>(); 
     for(T element : elements) 
     { 
      arrayElements.add(element); 
     } 

     return (T[])arrayElements.toArray(); 
    } 
} 

लेकिन मैं एक संकलक चेतावनी हो रही है:

यहाँ मैं क्या है 'नोट:। ... \ IterableHelp.java अनियंत्रित या असुरक्षित संचालन का उपयोग करता है'

इस तरह की चेतावनी से बचने वाले किसी अन्य दृष्टिकोण पर कोई विचार?

+2

मुझे लगता है चेतावनी है कि अंतिम पंक्ति पर है, जहां आप 'टी []' करने के लिए सरणी कास्टिंग कर रहे हैं? – MatrixFrog

+0

@MatrixFrog सही – Dejas

+2

भी देखें अमरूद के 'Iterables.toArray (Iterable , कक्षा )' –

उत्तर

27

Google Guava में Iterables.toArray एक विधि है।

the source को देखते हुए, यह रूप में परिभाषित किया है:

/** 
    * Copies an iterable's elements into an array. 
    * 
    * @param iterable the iterable to copy 
    * @param type the type of the elements 
    * @return a newly-allocated array into which all the elements of the iterable 
    *  have been copied 
    */ 
    public static <T> T[] toArray(Iterable<? extends T> iterable, Class<T> type) { 
    Collection<? extends T> collection = toCollection(iterable); 
    T[] array = ObjectArrays.newArray(type, collection.size()); 
    return collection.toArray(array); 
    } 

कहाँ ObjectArrays.newArray अंततः एक विधि है कि लग रहा है के प्रतिनिधियों की तरह:

/** 
    * Returns a new array of the given length with the specified component type. 
    * 
    * @param type the component type 
    * @param length the length of the new array 
    */ 
    @SuppressWarnings("unchecked") 
    static <T> T[] newArray(Class<T> type, int length) { 
    return (T[]) Array.newInstance(type, length); 
    } 

तो ऐसा लगता है कि कोई रास्ता नहीं @SuppressWarnings पूरी तरह से बचने के लिए है जैसे, लेकिन आप कम से कम इसे संभवतः सबसे छोटे संभव दायरे में बाध्य कर सकते हैं।

या, बेहतर अभी तक, किसी और के कार्यान्वयन का उपयोग करें!

2

unchecked or unsafe operations चेतावनी से छुटकारा पाने का कोई तरीका नहीं है, या आपके विधि हस्ताक्षर को संपादित किए बिना टाइपसेफ ऐरे बनाना कोई तरीका नहीं है।

इस bug report को गोरी विवरण के लिए देखें।

एक तरीका प्रकार T का एक पूर्व आवंटित सरणी में पारित करने के लिए है:

public class IterableHelp 
{ 
    public <T> T[] toArray(final T[] t, final Iterable<T> elements) 
    { 
     int i = 0; 
     for (final T element : elements) 
     { 
      t[i] = element; 
     } 
     return t; 
    } 
} 

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

यदि आप गतिशील रूप से टाइपसेफ सरणी बनाना चाहते हैं, तो आप वास्तव में जावा में टाइपसेफ तरीके से ऐसा नहीं कर सकते हैं।

यह काम करता है और संकलित है, लेकिन यह अनियंत्रित या असुरक्षित डाली मुद्दे को हल नहीं करता है, यह सिर्फ एक अलग जगह पर यह बढ़ता रहता है। कलाकारों के बारे में शिकायत करना बंद करने के लिए मुझे @SuppressWarnings एनोटेशन जोड़ना पड़ा।

@SuppressWarnings({"unchecked"}) 
public class IterableHelp 
{ 
    public <T> T[] toArray(Class<T> t, Iterable<T> elements) 
    { 
     final ArrayList<T> arrayElements = new ArrayList<T>(); 
     for (T element : elements) 
     { 
      arrayElements.add(element); 
     } 
     final T[] ta = (T[]) Array.newInstance(t, arrayElements.size()); 
     return arrayElements.toArray(ta); 
    } 
} 
0

आपको अनचेक चेतावनी से बड़ी समस्या मिली है। वास्तव में, यदि ऑब्जेक्ट के अलावा टी कुछ भी है तो यह रनटाइम पर क्लासकास्ट अपवाद फेंक देगा।

String[] foo = IterableHelp.toArray(new ArrayList<String>());

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

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