I have created a List
of Lists with a default size set. Therefore, I am adding the data to the lists using the set
method.
My Code:
package test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Test2 {
public static void main(String args[]) {
List<List<String>> keys = new ArrayList<>(Collections.nCopies(3, new ArrayList<>()));
List<String> values = keys.get(2);
values.add("Hello");
values.add("One Two");
keys.set(2, values);
List<String> tempList = keys.get(1);
tempList.add("Now adding at 1");
keys.set(1, tempList);
System.out.println("Position 1 " + keys.get(1).toString());
System.out.println("Position 2 " + keys.get(2).toString());
}
}
My Output:
Position 1 [Hello, One Two, Now adding at 1]
Position 2 [Hello, One Two, Now adding at 1]
Why is it doing this? The first data get's appended onto the second as well? What am I doing wrong ?
List<List<String>> keys = new ArrayList<>(Collections.nCopies(3, new ArrayList<>()))
In this statement it's not creating three new instances of ArrayList<>
. It creates one instance of it and creates a list with three references to the same instance. Hence each location in the list of lists is a reference to the same ArrayList
instance.
The simplest thing you can do to get around this is to use a for
loop:
for(int i = 0; i < numCopies; i++) {
keys.add(new ArrayList<>());
}
An equivalent solution using Java 8's streaming API:
IntStream.range(0, n).mapToObj(i -> new ArrayList<String>()).forEach(keys::add);
Or you can create keys
in one go like so:
List<List<String>> keys = IntStream.range(0, numCopies)
.mapToObj(i -> new ArrayList<String>())
.collect(Collectors.toList());
We use i -> new ArrayList<String>()
instead of ArrayList<String>::new
because there is an ArrayList<T>
constructor that takes in a single integer argument for the initial capacity, which means that it ends up actually being new ArrayList<String>(0)
, new ArrayList<String>(1)
, and so on, which is not what we want.
A more elegant option is to use Stream.generate
:
Stream.generate(ArrayList<String>::new).limit(n);
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