Add ArrayList to another ArrayList in java
I am having the following java code, in which I am trying to copy the ArrayList to another 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);
}
I want the "list" array to be in this format:
[[PropertyStart,a,b,c,PropertyEnd],[PropertyStart,d,e,f,PropertyEnd],[PropertyStart,......]]
But from the above code, the "list" array output is seen like this:
[PropertyStart,a,b,c,PropertyEnd,PropertyStart,d,e,f,PropertyEnd,PropertyStart,....PropertyEnd]
I think you might have noticed the difference. I am not able to achieve the result in expected format.
Solution 1:
Then you need a ArrayList
of ArrayLists
:
ArrayList<ArrayList<String>> nodes = new ArrayList<ArrayList<String>>();
ArrayList<String> nodeList = new ArrayList<String>();
nodes.add(nodeList);
Note that NodeList
has been changed to nodeList
. In Java Naming Conventions variables start with a lower case. Classes start with an upper case.
Solution 2:
Your Problem
Mainly, you've got 2 major problems:
You are using adding a List
of String
s. You want a List
containing List
s of Strings
.
Note as well that when you invoke this:
NodeList.addAll(nodes);
... all you say is to add all elements of nodes (which is a list of Strings) to the (badly named) NodeList
, which is using Objects and thus adds only the strings inside. Which leads me to the next point.
You seem to be confused between your nodes
and NodeList
. Your NodeList
keeps growing over time, and that's what you add to your list.
So, even if doing things right, if we were to look at the end of each iteration at your nodes
, nodeList
and list
, we'd see:
-
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]]
and so on...
Some Other Corrections
Follow the Java Naming Conventions
Don't use variable names starting with uppercase letters. So here, replace NodeList
with nodeList
).
Learn a Bit More About Types
You say "I want the "list" array [...]". This is confusing for whoever you will be communicating with: It's not an array. It's an implementation of List
backed by an array.
There's a difference between a type, an interface, and an implementation.
Use Generics for Stronger Typing in Collections
Use generic types, because static typing really helps with these errors. Also, use interfaces where possible, except if you have a good reason to use the concrete type.
So your code becomes:
List<String> nodes = new ArrayList<String>();
List<String> nodeList = new ArrayList<String>();
List<List<String>> list = new ArrayList<List<String>>();
Remove Unnecessary Code
You could do away with the nodeList
entirely, and write the following once you've fixed your types:
list.add(nodes);
Use the Right Scope
Except if you have a very strong reason to do so, prefer to use the inner-most scope to declare variables and limit both their lifespan for their references and facilitate the separation of concerns in your code.
Here you could then move List<String> nodes
to be declared within the loop (and then forget the nodes.clear()
invocation).
A reason not to do this could be performance, as you might want to avoid recreating an ArrayList
on each iteration of the loop, but it's very unlikely that's a concern to you (and clean, readable and maintainable code has priority over pre-optimized code).
SSCCE
Last but not least, if you want help give us the exact reproducible case with a short, self-Contained, correct example.
Here you give us your program's outputs, but don't mention how you got them, so we're left to assume you did a System.out.println(list)
. And you confused a lot of people, as I think the output you give us is not what you actually got.