2015-10-13 10 views
8

के लिए अज्ञात ArrayList प्रकार पासिंग मैं इन दो ArrayLists है कहते हैं:विधि

ArrayList<Book> book = new ArrayList<>(); 
ArrayList<Journal> journal = new ArrayList<>(); 

Book और Journal दो अलग-अलग वर्ग हैं।

Book और Journal दोनों वस्तुओं में getYear() विधि है। मैं एक ऐसी विधि बनाना चाहता हूं जो किसी अज्ञात ArrayList प्रकार में गुजरती है और सूची में किसी ऑब्जेक्ट में पास की गई वर्ष की तुलना करती है। निम्नलिखित कोड मुख्य में है:

public static void fooBar(int year, ArrayList<?> list) 
{ 
    if(list.get(0).getYear() == year) // does not work! 
    { 
    } 
} 

एक अज्ञात प्रकार विधि में पारित कर दिया गया है, तो मुझे लगता है कि वस्तु के तरीकों (getYear()) का उपयोग नहीं कर सकते हैं। मैं दो तरीकों के बिना ऐसा कैसे कर सकता हूं जो एक ही काम करता है (Book और Journal के लिए एक)?

+4

क्या 'बुक' और' जर्नल 'एक सुपरक्लास या इंटरफ़ेस साझा करता है जो' getYear() 'को परिभाषित करता है? – JonK

+0

मेरी विधि हस्ताक्षर गलत था, मैंने सवाल संपादित किया। – MortalMan

+1

क्या @ जोनके ने पूछा ... यदि आपको ऐसा नहीं करना चाहिए और इससे आपकी समस्या हल हो जाएगी – 3kings

उत्तर

13

आप एक इंटरफेस कर सकते हैं (यदि वह पहले नहीं मौजूद हैं) (संभवतः HasYear नाम) घोषणा करता है कि getYear() विधि, और Book और Journal इसे लागू किया है।

फिर आप fooBar विधि HasYear पर कुछ प्रकार पैरामीटर के ArrayList ले सकते हैं।

public static void fooBar(int year, ArrayList<? extends HasYear> list) 

? extends तथ्य यह एक उपभोक्ता और नहीं एक निर्माता है के कारण है।

+0

मैं स्कूल में जावा सीख रहा हूं और मैंने नहीं सीखा है कि एक इंटरफ़ेस क्या है। जावा विधि को उस प्रकार की सूची का अनुमान क्यों लगा सकता है जिसे मैं विधि में भेजता हूं ताकि मैं उस ऑब्जेक्ट के तरीकों का उपयोग कर सकूं? – MortalMan

+3

'सूची ' पैरामीटर के साथ, आपको किसी भी चीज़ की एक सूची पास करने की अनुमति है, उदा। 'सूची ',' सूची ',' सूची ', आदि, जिसमें' getYear()' विधि आवश्यक नहीं होगी। कंपाइलर आपको उस विधि को कॉल करने की अनुमति नहीं देगा, जिसकी गारंटी नहीं हो सकती है। – rgettman

+0

आपकी सूची विधि में 'सूची ' के रूप में निर्दिष्ट है, इसलिए इसमें कुछ भी शामिल हो सकता है। – khelwood

4

जैसा कि जॉन ने कहा, अगर वे एक सुपरक्लास या इंटरफ़ेस साझा करते हैं जो getYear() को परिभाषित करता है तो यह आसान हो जाएगा। असल में, में है जो आपके प्रस्तावित रिश्ते को बनाने के लिए उन दो रिश्तों में से एक है।

interface HasYear { 
    public int getYear(); 
} 

Book.java

public class Book implements HasYear{ 
    //... 
    public int getYear(){/*YOUR IMPLEMENTATION*/} 
} 

Journal.java

public class Journal implements HasYear{ 
    //... 
    public int getYear(){/*YOUR IMPLEMENTATION*/} 
} 

अब, आप बना सकते हैं और इस तरह से अपने ArrayList का उपयोग कर सकते हैं:

public static void fooBar(int year, ArrayList<? extends HasYear> list){ 
    if(list.get(0).getYear() == year){ 
     //yay 
    } 
} 
3

है दोनों Book और Journal विस्तार

public abstract class Publication { 
    private int year; 

    public int getYear() { 
     return year; 
    } 

    public Publication(int year) { 
     this.year = year; 
    } 
} 

आप तो अपने Book और Journal वर्ग घोषणाओं और निर्माताओं को बदलते हैं:

public class Book extends Publication { 

    public Book(int year, ...) { 
     super(year); 
     ... 
    } 
public class Journal extends Publication { 

    public Journal(int year, ...) { 
     super(year); 
     ... 
    } 
एक आम सुपर क्लास (? Publication शायद) या एक आम इंटरफ़ेस जो getYear() पद्धति निर्धारित करता है को लागू

फिर आप Publication ऑब्जेक्ट्स की एक सूची पास कर सकते हैं:

public void fooBar(int year, List<? extends Publication> list) { ... } 

क्योंकि यह Publication है जो getYear() विधि को परिभाषित करता है, तो आप इसे list में निहित वस्तुओं पर आसानी से उपयोग कर सकते हैं।

+0

जैसा कि अन्य उत्तरों ने दिखाया है, आप एक ही चीज़ को एक ही तरीके से पूरा करने के लिए एक इंटरफ़ेस का उपयोग भी कर सकते हैं। 'सूची ' का उपयोग करके – JonK

+2

'तर्क के रूप में आपको 'list' की सामग्री के वास्तविक प्रकार की परवाह किए बिना' list.add (new book()) 'कॉल करने की अनुमति देता है, जो बहुत खतरनाक है। '? प्रकाशन बढ़ाता है 'इसे रोकता है। – njzk2

+0

@ njzk2 मुझे लगता है कि यह वास्तव में इस बात पर निर्भर करता है कि आप सूची के साथ क्या कर रहे हैं, लेकिन हाँ, बिंदु ले लिया। मैं जवाब अपडेट करूंगा। – JonK

1

हर कोई इस तरह के अपने वांछित विधि युक्त एक सुपर वर्ग के साथ अपने ऑब्जेक्ट जोड़ रूप में, यह ऐसा करने का सही तरीका बारे में चर्चा की है, लेकिन अगर आप सुपर वर्ग का उपयोग किए बिना कुछ फैंसी कार्यान्वयन चाहते हैं, आप लैम्ब्डा अभिव्यक्ति की कोशिश कर सकते हैं:

ArrayList<Book> book = new ArrayList<>(); 
book.stream().limit(1).filter(s->s.getYear()==year).forEach(yourcode) 

मुझे पता है कि यह वही नहीं है जो आप चाहते थे लेकिन आपके पास अन्य टिप्पणियों का सही समाधान है।