簡體   English   中英

Java 中深度嵌套的 hashmap

[英]Deeply nested hashmaps in Java

我已使用此示例在 Java 中訪問深度嵌套的 HashMap構建數據結構以存儲節點名稱和屬性。

這是更新后的代碼:

class NestedMap {

private final HashMap<String, NestedMap> child;

private Map<String, Object> value = new HashMap<>();

public NestedMap() {
    child = new HashMap<>();
    setValue(null);
}

public boolean hasChild(String k) {
    return this.child.containsKey(k);
}

public NestedMap getChild(String k) {
    return this.child.get(k);
}

public void makeChild(String k) {
    this.child.put(k, new NestedMap());
}

public Map<String, Object> getValue() {
    return value;
}

public void setValue(Map<String, Object> value) {
    this.value = value;
}

}

我的用法示例:

    class NestedMapIllustration {
        public static void main(String[] args) {

        NestedMap m = new NestedMap();

        m.makeChild("de");
        m.getChild("de").makeChild("content");
        m.getChild("de").getChild("content").makeChild("00");
        m.getChild("de").getChild("content").makeChild("0");
        m.getChild("de").getChild("content").makeChild("1");
        m.getChild("de").getChild("content").makeChild("01");
        m.getChild("de").getChild("content").getChild("01").makeChild("fieldsets");
        m.getChild("de").getChild("content").getChild("01").getChild("fieldsets").makeChild("0");
        m.getChild("de").getChild("content").getChild("01").getChild("fieldsets").getChild("0").makeChild("fields");
        m.getChild("de").getChild("content").getChild("01").getChild("fieldsets").getChild("0").getChild("fields").makeChild("0");
        Map<String, Object> properties = new HashMap<>();
        properties.put("key", "value");
        properties.put("key2", "value");
        m.getChild("de").getChild("content").getChild("01").getChild("fieldsets").getChild("0").getChild("fields").setValue(properties);
}

我不想為每個值創建一個新對象,而是始終創建一個新的 HashMap ,我可以在其中存儲節點屬性。

我通過訪問 JCR 數據存儲中的節點並提取它們的值和屬性來接收我的數據結構。 這是我生成的數據結構在輸出 yaml 文件中的樣子:

在此處輸入圖像描述

我怎樣才能更有效地做到這一點?

你特意讓你使用任何鍵,但你使用的是字符串鍵,即使其中一個鍵是"01" ,這表明它是一個數字。

我可以由此得出結論,鍵總是字符串嗎?

在那種情況下,為什么不定義一個分隔符,比如斜杠,並使用普通的舊TreeMap<String, V> 然后你可以這樣做:

m.put("de/content/01/fieldsets/0/fields", properties);

如果你想要de/content/01 '樹' 中的所有內容,你可以這樣做:

m.subMap("de/content/01/", "de/content/010");

以上將為您提供包含 de/content/01 的每個子項的地圖。 010末尾的0具有“魔力”:零是 ascii 表中斜線后的下一個字符。

如果您希望任何給定的鍵映射到任意數量的值,您可以使用:

TreeMap<String, List<V>> map = new TreeMap<>();

把東西放進去:

map.computeIfAbsent(key, k -> new ArrayList<>()).add(elem);

並把事情弄清楚:

for (V value : map.getOrDefault(key, List.of())) {
    // works even if key isn't in there (loops 0 times then)
}

使用遞歸解決問題

public HashMap<String,Object> nestedMap(Node node) {

           HashMap<String, Object> map = new LinkedHashMap<>();

           PropertyIterator pi;
            try {
                pi = node.getProperties();
                //Get properties for the root node
                   while(pi.hasNext())
                    {
                       Property p = pi.nextProperty();
                       String name = p.getName();
                       String val = p.getString();

                       map.put(name,val);

                    }//end of while for properties of root node
            } catch (RepositoryException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }


           Iterable<Node> children;
            try {
                children = NodeUtil.getNodes(node);
                for (Node child : children) {

                    if (!child.getPrimaryNodeType().getName().contains("mgnl:page")) {  
                      map.put (child.getName(), nestedMap(child));

                   }//end of checking if PrimaryNodeType is of type mgnl:page
                }

            } catch (RepositoryException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            return map;
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM