The clone() method of the ArrayList class is used to clone an ArrayList to another ArrayList in Java as it returns a shallow copy of its caller ArrayList.
In order to copy elements of ArrayList to another ArrayList, we use the Collections. copy() method. It is used to copy all elements of a collection into another. where src is the source list object and dest is the destination list object.
The addAll() method is used to add all the elements from one ArrayList to another ArrayList.
If you have an arraylist of String called 'foo', you can easily append (add) it to another ArrayList, 'list', using the following method: ArrayList<String> list = new ArrayList<String>(); list. addAll(foo);
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.
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...
Don't use variable names starting with uppercase letters. So here, replace NodeList
with nodeList
).
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 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>>();
You could do away with the nodeList
entirely, and write the following once you've fixed your types:
list.add(nodes);
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).
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.
Wouldn't it just be a case of:
ArrayList<ArrayList<String>> outer = new ArrayList<ArrayList<String>>();
ArrayList<String> nodeList = new ArrayList<String>();
// Fill in nodeList here...
outer.add(nodeList);
Repeat as necesary.
This should return you a list in the format you specified.
The problem you have is caused that you use the same ArrayList NodeList over all iterations in main for loop. Each iterations NodeList is enlarged by new elements.
After first loop, NodeList has 5 elements (PropertyStart,a,b,c,PropertyEnd) and list has 1 element (NodeList: (PropertyStart,a,b,c,PropertyEnd))
After second loop NodeList has 10 elements (PropertyStart,a,b,c,PropertyEnd,PropertyStart,d,e,f,PropertyEnd) and list has 2 elements (NodeList (with 10 elements), NodeList (with 10 elements))
To get you expectations you must replace
NodeList.addAll(nodes);
list.add(NodeList)
by
List childrenList = new ArrayList(nodes);
list.add(childrenList);
PS. Your code is not readable, keep Java code conventions to have readble code. For example is hard to recognize if NodeList is a class or object
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With