2013-01-24 13 views
7

मैं कार्यात्मक लैंगुग जैसे स्कीम और हास्केल से बहुत परिचित हूं। मैं जावा में एक समस्या को हल करने और संघर्ष करने की कोशिश कर रहा हूं, संभवतः क्योंकि मैं अभी भी एक कार्यात्मक मानसिकता में हूं।जावा हायर ऑर्डर पॉलीमोर्फिक फ़ंक्शन

मैं लिखना चाहते हैं:

public void doQueryAndStoreData(String query, <? extends Collection> storeIn) { 
    /* make a jdbc query, get ResultSet */ 
    ResultSet rset = ...; 
    ProcessResultSet proc = new ProcessResultSet(); 
    proc.process(rset, storeIn); 
    /* clean up */ 
} 
साथ

एक इंटरफेस की तरह:

private interface IProcessResultSet<C> { 
    public void process(ResultSet rset, C storeIn); 
} 

और एक वर्ग की तरह इंटरफ़ेस को लागू करने:

private class ProcessResultSet implements IProcessResultSet<? extends Collection> { 
    public void process(ResultSet rset, Map storeIn) { 
     /* do something */ 
    } 

    public void process(ResultSet rset, List storeIn) { 
     /* do something else */ 
    } 
} 

ताकि पहली विधि कॉल कर सकते हैं उपयुक्त process किस प्रकार के storeIn पर दिया गया है इसके आधार पर।

हास्केल में मैं

class Storeable c a where 
    store :: a -> c a -> c a 

doQueryAndStoreData :: Storeable c a => ResultSet a -> c a -> c a 
doQueryAndStoreData (ResultSet rs) coll = foldr store coll rs 

लिख सकते हैं और मैं अपने ResultSet में संग्रहीत करना चाहते हैं जो कुछ भी संग्रह प्रकार के लिए Storeable उदाहरणों प्रदान कर सकता है।

इस जावा में सही दृष्टिकोण है? क्योंकि मुझे लगता है कि मैं इसे पूरा करने के लिए कुछ हद तक लंगेज से लड़ रहा हूं।

+1

मुझे लगता है कि आपको विज़िटर पैटर्न - डबल प्रेषण का उपयोग करके हल करने के लिए क्या हल किया जा सकता है। – Scorpion

+0

व्यक्तिगत रूप से, मैं एक समारोह से कुछ वापस करने के लिए और अधिक उपयुक्त होगा। कोड को और अधिक पठनीय बनाने के लिए जाता है। मानचित्र और सूची में निकटतम सुपरटेप के बारे में नहीं सोच सकते हैं, लेकिन यह वापसी मूल्य होगा, और फिर असाइनमेंट स्टेटमेंट में मानचित्र/सूची में डाला जाएगा, यानी, मानचित्र myMap = नया मानचित्र ; myMap = (मानचित्र ) प्रक्रिया (rset, myMap); " – anthropomo

उत्तर

2

नहीं है, जावा ऐसा नहीं करता है।

आप की तरह कुछ करने के लिए आवश्यकता होगी:

public <T> void doQueryAndStoreData(
    String query, 
    T storeIn, 
    ResultSetProcessor<T> processor 
) { 

या और अधिक होने की संभावना:

public void doQueryAndStoreData(
    String query, 
    ResultSetHandler handler // may contain processor and storeIn 
) { 

मुझे आशा है कि मैं एसक्यूएल इंजेक्शन कमजोरियों एक बुरी बात कर रहे हैं उल्लेख करने के लिए जरूरत नहीं है। (Map जावा में Collection नहीं है (यह सी # में है लेकिन सी # Collection बहुत उपयोगी नहीं है)।

2

दुर्भाग्य से आप ऐसा नहीं कर सकते हैं। कंपाइलर को संकलन समय पर पता होना चाहिए कि यह कॉल किस प्रकार से जुड़ी है। आप कौन सी विधि वस्तु के क्रम प्रकार के आधार पर कॉल करने के लिए तय करने के लिए चाहते हैं, तो आप मैन्युअल रूप से यह जांच करने के लिए है:

सबसे आप कर सकते हैं:

private class ProcessResultSet implements IProcessResultSet<? extends Collection> { 

    @Override 
    public void process(ResultSet rset, Collection storeIn) { 
     if (storeIn instanceof Set) { 
      return processSet(rset, (Set) storeIn); 
     } else if (storeIn instanceof List) { 
      return processList(rset, (List) storeIn); 
     } else { 
      throw new IllegalArgumentException("Unimplemented storage type"); 
     } 
    } 


    public void processSet(ResultSet rset, Set storeIn) { 
     /* do something */ 
    } 

    public void processList(ResultSet rset, List storeIn) { 
     /* do something else */ 
    } 
} 
0
private class ProcessResultSet implements IProcessResultSet<? extends Collection> { 

    public void process(ResultSet rset, Object storeIn) 
    { 
     if (storeIn instanceof Map) 
      processMap(rset,(Map) storeIn); 
     else if (storeIn instanceof List) 
      processList(rset,(List) storeIn); 
     else 
      System.out.println("Unsupported input type."); 
    } 

    public void processMap(ResultSet rset, Map storeIn) { 
     /* do something */ 
    } 

    public void processList(ResultSet rset, List storeIn) { 
     /* do something else */ 
    } 
} 
+0

मैं 1 मिनट देर से हूं ... –

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