Hashmap,键为String,Value为ArrayList,包含元素迭代问题

时间:2014-08-20 11:15:37

标签: java dom for-loop arraylist hashmap

我有一个HashMap,它接受一个String作为Key,一个ArrayList作为Value。

我为此写的逻辑是:         List lsChildLine = new ArrayList();

NodeList nlBook = doc.getElementsByTagName("Book");

for(int cnt=0; cnt < nlBook.getLength() ; cnt++){

Element elBook = (Element) nlBook.item(cnt);

Element childLine = Util.getChildElement(elBook , "ChildLine");
Element parentLine = Util.getChildElement(elBook , "ParentLine");

String parentLineNo = parentLine.getAttribute("LineNo");

if(!mapParentAndChildLines.containsKey(parentLineNo)){

            lsChildLine.add(childLine);

            mapParentAndChildLines.put((parentLineNo), lsChildLine);

        }else{

            lsChildLine =  mapParentAndChildLines.get(parentLineNo);
            lsChildLine.add(childLine);

            mapParentAndChildLines.put((parentLineNo), lsChildLine);

        }

}

现在我必须根据每个键的列表大小做一些逻辑。

当我是循环播放的xml时,这工作正常如下:

    <BookShelf>
    <Book Name="ABC">
        <ParentLine LineNo="1">
        <ChildLine LineNo="2">
    </Book>
   </BookShelf>

但是,当xml像:

时,这不起作用
    <BookShelf>
    <Book Name="ABC">
        <ParentLine LineNo="1">
        <ChildLine LineNo="2">
    </Book>
    <Book Name="ABC">
        <ParentLine LineNo="3">
        <ChildLine LineNo="4">
    </Book>
   </BookShelf>

在这种情况下,当第一次迭代循环时,mapNo不存在于地图中,因此将ChildLine元素添加到列表中。

当循环第二次迭代时,该键也不存在于映射中,因此它进入If块。现在列表对象已经具有循环中前一个Element的ChildLine,并且对应于新键的childLine被插入到同一个循环中,因此当理想情况下它应该是1时,列表大小变为2。 / p>

我无法想出一个合适的逻辑来避免这种情况,尽管我觉得这与在正确的位置对List进行decal有关。

对此有何帮助?

1 个答案:

答案 0 :(得分:1)

您只在代码中创建一个列表,因此所有元素都将添加到同一列表中。而是为每个新parentLineNo创建一个新列表。

if(!mapParentAndChildLines.containsKey(parentLineNo)){

    // Create a new list to add in the map
    lsChildLine = new ArrayList();
    lsChildLine.add(childLine);

    mapParentAndChildLines.put((parentLineNo), lsChildLine);

}else{

    lsChildLine =  mapParentAndChildLines.get(parentLineNo);
    lsChildLine.add(childLine);

    // Unnecessary, the list is already in the map
    // mapParentAndChildLines.put((parentLineNo), lsChildLine);

}