2010-03-14 14 views
5

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

foo(String filename, Hashmap<String, Object> map) 
{ 
    //some stuff here 
    for (Entry<String, Object> entry : map.entrySet()) 
    { 
     //type warning that must be suppressed 
     foo(entry.getKey(), (HashMap<String, Object>)entry.getValue()); 
    } 
} 

मैं जानता हूँ कि यह सुनिश्चित करें Object के लिए प्रकार Hashmap<String, Object> की है, लेकिन चिढ़ मैं चेतावनी @SuppressWarnings("unchecked") का उपयोग कर दबाने के लिए है कि कर रहा हूँ।

मैं ऐसे समाधान से संतुष्ट हूं जो assert(/*entry.getValue() is of type HashMap<String, Object>*/) करता है या जब यह नहीं होता है तो अपवाद फेंकता है। मैं संकलन प्रकार सुरक्षा के लिए जेनेरिक मार्ग नीचे गया और यदि मैं चेतावनी दबाता हूं तो यह उद्देश्य को हरा देता है।

अपनी टिप्पणी के लिए धन्यवाद, KSB

उत्तर

5

यह एक पुनरावर्ती प्रकार चर के साथ एक सामान्य विधि का उपयोग संभव है। निम्न का प्रयास करें:

public <T extends Map<String, T>> void foo(String filename, T map) { 
    //some stuff here 
    for (Map.Entry<String, T> entry : map.entrySet()) { 
     foo(entry.getKey(), entry.getValue()); 
    } 
} 

किसी भी चेतावनी के बिना ठीक संकलित करना चाहिए।

हालांकि, यदि आपके पास मानचित्र का नियंत्रण है, और अपनी खुद की कक्षा को प्रतिस्थापित कर सकता है, तो यह कक्षा नोड (यह मेरे लिए एक पेड़ जैसा दिखता है) बनाने के लिए और अधिक पठनीय हो सकता है, में एक मानचित्र है। की तरह कुछ:

public class Node { 
    private Map<String, Node> children; 

    ... 
    // accessor methods to retrieve children ... 
} 

और foo एक Node अपनी दूसरी तर्क के रूप में के बजाय लेने के लिए। केवल एक सलाह।

+0

प्रिय वैक्सविंग, मैंने आपके दूसरे सुझाव को लागू करने का अंत किया क्योंकि यह पता चला है कि मुझे किसी अन्य हैशप के संदर्भ के बजाय "नोड" में अतिरिक्त चीजें जोड़ने की आवश्यकता है। यह भी अधिक प्राकृतिक लगता है। मैं सिर्फ जावा के साथ पकड़ने जा रहा हूं, इसलिए आपका पहला सुझाव समझ नहीं सकता - "टी मानचित्र " भाग बढ़ाता है। एक बार फिर धन्यवाद, केएसबी –

5

आप HashMap के बजाय इस वर्ग का उपयोग कर सकते हैं:

public class RecursiveHashMap extends HashMap<String,RecursiveHashMap> 
{ 
} 
+0

प्रिय हा, वास्तव में यह समझ में नहीं आता कि यह क्यों काम कर सकता है (जावा नोब), इसलिए इसे आजमाया नहीं गया। मैं वैक्सविंग के नोड समाधान के साथ जा रहा हूँ। धन्यवाद, केएसबी –

+0

हाँ, 'नोड' वर्ग (उर्फ समग्र पैटर्न) बनाना 'हैश मैप' से बेहतर तरीका है। –

1

आपकी डेटा संरचना ऐसा लगता है कि आप इसके साथ फ़ाइलों के पेड़ (फ़ाइल नाम) का प्रतिनिधित्व करना चाहते हैं। मैं हैश मैप के साथ नोड प्रकार के रूप में ऐसा करने की अनुशंसा नहीं करता।

मैं समग्र पैटर्न (विकिपीडिया देखें), का उपयोग करने के लिए सरल कोड सुझाव देंगे: DirectoryNode में प्रदर्शित होने के सेट करने के लिए नीचे

abstract class Node 
{ 
    String filename; 
    Node(String filename) { this.filename = filename; } 
    abstract foo(); 
} 

class FileNode implements Node 
{ 
    FileNode(String filename) { super(filename); } 
    foo() { ... } 
} 

class DirectoryNode implements Node 
{ 
    Set<Node> children; 
    DirectoryNode(String filename, Set<Node> children) 
    { 
    super(filename); 
    this.children = children; 
    } 
    foo() 
    { 
    for (Node child : children) child.foo(); 
    } 
} 

HashMap आप उपयोग कर रहे थे फोड़े।

+0

विचार के लिए धन्यवाद। मेरी संस्थाओं को स्वाभाविक रूप से दो नोड प्रकारों में विभाजित नहीं किया जा सकता है यानी निर्देशिका और फ़ाइलें। वे सभी "फ़ाइलें" हैं। विशेष रूप से मुझे पदानुक्रम की सभी परतों पर एक ही प्रसंस्करण foo() करने की आवश्यकता है। मैं इसे पूरा करने के लिए अपना कोड बढ़ाने में सक्षम नहीं हूं। –

+0

क्यों नहीं? आप DirectoryNode.foo() में आवश्यक सभी कोड डाल सकते हैं। आप कोड को नोड में भी डाल सकते हैं।foo() और फिर DirectoryNode.foo() पर super.foo() को कॉल करें। फिर नोड आपकी फाइल होगी। – Wolfgang

+0

मैं देख रहा हूं कि आप क्या कह रहे हैं: सामान्य कोड को नोड के अंदर रखें (foo अब सार नहीं है) और फ़ाइल और निर्देशिका कॉल सुपर (फ़ाइल नाम) है। उसे याद होगा। धन्यवाद, केएसबी –