30

我有以下 java 代码,我在其中尝试将 ArrayList 复制到另一个 ArrayList。

ArrayList<String> nodes = new ArrayList<String>();
ArrayList NodeList = new ArrayList();
ArrayList list = new ArrayList();

for (int i = 0; i < PropertyNode.getLength() - 1; i++) {
    Node childNode = PropertyNode.item(i);
    NodeList Children = childNode.getChildNodes();

    if (Children != null) {
        nodes.clear();
        nodes.add("PropertyStart");
        nodes.add(Children.item(3).getTextContent());
        nodes.add(Children.item(7).getTextContent());
        nodes.add(Children.item(9).getTextContent());
        nodes.add(Children.item(11).getTextContent());
        nodes.add(Children.item(13).getTextContent());
        nodes.add("PropertyEnd");
    }
    NodeList.addAll(nodes);
    list.add(NodeList);
}

我希望“列表”数组采用这种格式:

[[PropertyStart,a,b,c,PropertyEnd],[PropertyStart,d,e,f,PropertyEnd],[PropertyStart,......]]

但是从上面的代码中,“list”数组输出是这样的:

[PropertyStart,a,b,c,PropertyEnd,PropertyStart,d,e,f,PropertyEnd,PropertyStart,....PropertyEnd]

我想你可能已经注意到了不同之处。我无法达到预期格式的结果。

4

6 回答 6

46

然后你需要ArrayList一个ArrayLists

ArrayList<ArrayList<String>> nodes = new ArrayList<ArrayList<String>>();
ArrayList<String> nodeList = new ArrayList<String>();
nodes.add(nodeList);

请注意,NodeList已更改为nodeList. 在Java 命名约定中,变量以小写字母开头。类以大写字母开头。

于 2013-05-24T08:07:47.453 回答
15

你的问题

主要是,你有两个主要问题:

您正在使用添加 a Listof Strings。你想要一个List包含Lists 的Strings.

另请注意,当您调用它时:

NodeList.addAll(nodes);

...您所说的只是将节点的所有元素(这是字符串列表)添加到NodeList使用对象的 (badly named) 中,因此只添加里面的字符串。这将我引向下一点。

您似乎对您的nodes和感到困惑NodeList。您NodeList会随着时间的推移不断增长,这就是您添加到列表中的内容。

所以,即使做对了,如果我们在你的nodes,nodeList和处查看每次迭代的结束list,我们会看到:

  • 我 = 0

    nodes: [PropertyStart,a,b,c,PropertyEnd]
    nodeList: [PropertyStart,a,b,c,PropertyEnd]
    list: [[PropertyStart,a,b,c,PropertyEnd]]
    
  • 我 = 1

    nodes: [PropertyStart,d,e,f,PropertyEnd]
    nodeList: [PropertyStart,a,b,c,PropertyEnd, PropertyStart,d,e,f,PropertyEnd]
    list: [[PropertyStart,a,b,c,PropertyEnd],[PropertyStart,a,b,c,PropertyEnd, PropertyStart,d,e,f,PropertyEnd]]
    
  • 我 = 2

    nodes: [PropertyStart,g,h,i,PropertyEnd]
    nodeList: [PropertyStart,a,b,c,PropertyEnd,PropertyStart,d,e,f,PropertyEnd,PropertyStart,g,h,i,PropertyEnd]
    list: [[PropertyStart,a,b,c,PropertyEnd],[PropertyStart,a,b,c,PropertyEnd, PropertyStart,d,e,f,PropertyEnd],[PropertyStart,a,b,c,PropertyEnd,PropertyStart,d,e,f,PropertyEnd,PropertyStart,g,h,i,PropertyEnd]]
    
  • 等等...

其他一些更正

遵循 Java 命名约定

不要使用以大写字母开头的变量名。所以在这里,替换NodeListnodeList)。

进一步了解类型

你说“我想要“列表”数组[...]”。这对于您将与之通信的任何人来说都是令人困惑的:它不是一个数组。它是List由数组支持的实现。

类型、接口和实现之间是有区别的。

使用泛型加强集合中的类型

使用泛型类型,因为静态类型确实有助于解决这些错误。此外,尽可能使用接口,除非您有充分的理由使用具体类型。

所以你的代码变成:

List<String> nodes = new ArrayList<String>();
List<String> nodeList = new ArrayList<String>();
List<List<String>> list = new ArrayList<List<String>>();

删除不必要的代码

您可以完全取消nodeList,并在修复类型后编写以下内容:

list.add(nodes);

使用正确的范围

除非您有非常充分的理由这样做,否则更喜欢使用最内部的范围来声明变量并限制它们的生命周期以供引用,并促进代码中关注点的分离。

然后,您可以在此处移动List<String> nodes以在循环中声明(然后忘记nodes.clear()调用)。

不这样做的一个原因可能是性能,因为您可能希望避免ArrayList在循环的每次迭代中重新创建一个,但这不太可能是您关心的问题(并且干净、可读和可维护的代码优先于预优化代码) .

SSCCE

最后但并非最不重要的一点是,如果您需要帮助,请通过简短、独立、正确的示例向我们提供确切的可重现案例。

在这里,您向我们提供了程序的输出,但没有提及您是如何获得它们的,所以我们假设您做了一个System.out.println(list). 你让很多人感到困惑,因为我认为你给我们的输出并不是你实际得到的。

于 2013-05-24T08:15:20.167 回答
3

不就是这样的情况吗:

ArrayList<ArrayList<String>> outer = new ArrayList<ArrayList<String>>();
ArrayList<String> nodeList = new ArrayList<String>();

// Fill in nodeList here...

outer.add(nodeList);

必要时重复。

这应该以您指定的格式返回一个列表。

于 2013-05-24T08:09:02.647 回答
1

您遇到的问题是您在 main for 循环中的所有迭代中使用相同的 ArrayList NodeList 。每次迭代NodeList都会被新元素放大。

  1. 第一次循环后,NodeList有 5 个元素(PropertyStart,a,b,c,PropertyEnd),列表有 1 个元素(NodeList: (PropertyStart,a,b,c,PropertyEnd))

  2. 在第二个循环之后NodeList有 10 个元素(PropertyStart,a,b,c,PropertyEnd,PropertyStart,d,e,f,PropertyEnd)并且列表有 2 个元素(NodeList(有 10 个元素),NodeList(有 10 个元素))

为了得到你的期望,你必须更换

NodeList.addAll(nodes);
list.add(NodeList)

经过

List childrenList = new ArrayList(nodes);
list.add(childrenList);

PS。您的代码不可读,请保持 Java 代码约定以具有可读代码。例如,很难识别 NodeList 是类还是对象

于 2013-05-24T08:36:49.233 回答
0

在 for 循环中启动 NodeList,您将获得所需的输出。

ArrayList<String> nodes = new ArrayList<String>();
 ArrayList list=new ArrayList();

        for(int i=0;i<PropertyNode.getLength()-1;i++){
            ArrayList NodeList=new ArrayList();
            Node childNode =  PropertyNode.item(i);
                NodeList Children = childNode.getChildNodes();

                if(Children!=null){
                    nodes.clear();
                    nodes.add("PropertyStart");
                    nodes.add(Children.item(3).getTextContent());
                    nodes.add(Children.item(7).getTextContent());
                    nodes.add(Children.item(9).getTextContent());
                    nodes.add(Children.item(11).getTextContent());
                    nodes.add(Children.item(13).getTextContent());
                    nodes.add("PropertyEnd");

                }   
                NodeList.addAll(nodes);
                list.add(NodeList);
        }

说明: NodeList 是一个在整个循环中保持不变的对象,因此在循环中将相同的变量添加到列表实际上只会添加一次。该循环仅将其变量添加到单个 NodeList 数组中,因此您必须看到

[/*list*/    [  /*NodeList*/   ]   ]

并且 NodeList 包含 [prostart, a,b,c,proend,prostart,d,e,f,proend ...]

于 2013-05-24T08:32:18.527 回答
0

首先将声明外部 Arraylist,其中将包含另一个内部 Arraylist

ArrayList> CompletesystemStatusArrayList; ArrayList systemStatusArrayList

CompletesystemStatusArrayList=新的 ArrayList

systemStatusArrayList=new ArrayList();

    systemStatusArrayList.add("1");
    systemStatusArrayList.add("2");
    systemStatusArrayList.add("3");
    systemStatusArrayList.add("4");
    systemStatusArrayList.add("5");
    systemStatusArrayList.add("6");
    systemStatusArrayList.add("7");
    systemStatusArrayList.add("8");

    CompletesystemStatusArrayList.add(systemStatusArrayList);
于 2013-09-30T09:36:40.827 回答