在Java中将ArrayList添加到另一个ArrayList中

32

我有以下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);
}

我希望 "list" 数组的格式是这样的:

[[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
不要使用原始列表,使用通用类型,你就会看到问题所在... - jlordo
5
请使用小写字母开头命名变量。 - Keppil
1
@Keppil,感谢您的建议。我会从现在开始改正自己。 - Mahe
6个回答

48

那么你需要一个 ArrayListArrayLists

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

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


15

你的问题

主要来说,你有两个主要问题:

你正在添加一个 ListString。你想要一个包含 StringList

还要注意一点,当你调用这个函数时:

NodeList.addAll(nodes);

你所说的都是要添加节点元素(一个字符串列表)到(名称不当的)NodeList 中,该列表使用对象,因此仅添加其中的字符串。这导致了下一个问题。

你好像把你的 nodesNodeList 搞混了。你的 NodeList 随着时间的推移不断增长,而这就是你要添加到列表中的内容。

所以,即使做得正确,如果我们在每次迭代结束时查看你的 nodesnodeListlist,我们会看到:

  • i = 0

    nodes: [PropertyStart,a,b,c,PropertyEnd]
    nodeList: [PropertyStart,a,b,c,PropertyEnd]
    list: [[PropertyStart,a,b,c,PropertyEnd]]
    
  • i = 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]]
    
  • i = 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命名约定

不要使用以大写字母开头的变量名。因此,在这里,将NodeList替换为nodeList)。

学习更多关于类型的知识

您说:“我想要“list”数组[...]”。对于您将与之交流的人来说,这很令人困惑:它不是一个数组。它是由数组支持的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)。并且你让很多人感到困惑,因为我认为你给我们的输出并不是你实际得到的。


3
这只是一个例子,不是真正需要翻译的内容。请提供需要翻译的文本。
ArrayList<ArrayList<String>> outer = new ArrayList<ArrayList<String>>();
ArrayList<String> nodeList = new ArrayList<String>();

// Fill in nodeList here...

outer.add(nodeList);

根据需要重复执行。

这将以您指定的格式返回列表。


1
您遇到的问题是在主循环中使用相同的ArrayList NodeList 导致的。每次迭代都会向NodeList添加新元素。

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

  2. 第二次循环后,NodeList有10个元素(PropertyStart,a,b,c,PropertyEnd,PropertyStart,d,e,f,PropertyEnd),而list有2个元素(NodeList(共有10个元素),NodeList(共有10个元素))

为了满足您的期望,您必须替换

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

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

PS. 你的代码不易读,保持Java编码规范以获得易读的代码。例如,很难识别NodeList是类还是对象。


0

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

ArrayList CompletesystemStatusArrayList; ArrayList systemStatusArrayList

CompletesystemStatusArrayList=new 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);


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 ...]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接