I have a nested ArrayList of the form
ArrayList<ArrayList<PointF>> nestedArraylist
I want to create a "copy" nestedArraylistCopy of nestedArraylist in the following sense:
The elements of nestedArraylistCopyshould be independent copies of the elements in nestedArraylist, i.e. should be ArrayLists holding the references to the same PointF objects in the original nestedArraylist.
Can I somehow use Collections.copy(dest, src) to do what I want? The documentation is not exactly detailed unfortunately...
Does the following code do what I want?
for(int i = 0; i < nestedArraylist.size(); i++)
nestedArraylistCopy.add(new ArrayList<PointF>(nestedArraylist.get(i)));
Is there a more efficient and or elegant solution?
Q1: after you Collections.copy, your new List object will contain the same elements as src (assuming the size is the same) which means, it holds same ArrayList<PointF> objects, hence the PointF objects are the same too. If you cannot get the info you want from the api java doc, read the source codes.
Q2: What you did is different from Collections.copy, since your copied arrayList has new Arraylist<PointF> as elements, but they contain the same elements (PointF) as the source list.
Q3: I don't know. because I don't know what do you want to have eventually. All new objects? Only ArrayList should be new objects, or all references?
According to my knowledge your solutions will update only references, as does Collection.copy(). You can use the below method, which I prefer:
List<ArrayList<PointF>> newList = new ArrayList<ArrayList<PointF>>(oldList);
A change of the old list would not affected to new list.
I tested your second option and it also has the property that changes to the old one will not affect the new List.
Note - These will also update only the references. If you change elements in your new list it will update old list too. I think Your second array will create brand new objects, but I am not 100% sure about that. I am adding my testing code below for you reference.
package test;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Lasitha Benaragama on 4/28/14.
*/
public class StckTest {
public static void main(String[] args) {
List<String> oldList = new ArrayList<String>();
oldList.add("AAAAA");
oldList.add("BBBBB");
oldList.add("CCCCC");
oldList.add("DDDDDD");
oldList.add("EEEEEE");
StckTest test = new StckTest();
List<String> newListCopy = new ArrayList<String>(oldList);
List<String> newListClone = new ArrayList<String>();
for(int i = 0; i < oldList.size(); i++)
newListClone.add(oldList.get(i));
test.printArray(newListCopy);
test.changeList(oldList);
test.printArray(oldList);
test.printArray(newListCopy);
test.printArray(newListClone);
}
public void changeList(List<String> oldList) {
oldList.remove(2);
oldList.add("FFFFF");
}
public void printArray(List<String> oldList){
for(int i = 0; i < oldList.size(); i++){
System.out.print(oldList.get(i)+",");
}
System.out.println();
}
}
You can use the clone() method to make a shallow copy of your object.
ArrayList<ArrayList<String>> nestedArraylist=new ArrayList<ArrayList<String>>();
ArrayList<String> x=new ArrayList<String>();
x.add("Deepak");
nestedArraylist.add(x);
System.out.println(nestedArraylist);
ArrayList<ArrayList<String>> nestedArraylistcopy=(ArrayList<ArrayList<String>>)nestedArraylist.clone();
System.out.println(nestedArraylistcopy);
Related
I need to write out a method to clone a nested ArrayList.
The nested ArrayList looks like this:
ArrayList<ArrayList<Ship>> theSea = new ArrayList<ArrayList<Ship>>();
I want to copy it to a clone:
ArrayList<ArrayList<Ship>> seaClone = new ArrayList<ArrayList<Ship>>();
I've tried iterating it and copying over the lists:
for(int i = 0; i < theSea.size(); i++){
seaClone.add(theSea.get(i));
}
However, this doesn't clone the elements of the nested ArrayList<Ship> and instead just copies over a reference to it.
How should I go about cloning the elements of the nested ArrayList<Ship>?
However, this doesn't clone the elements of the nested ArrayList
and instead just copies over a reference to it.
Because it is actually what you are doing : you add the reference of the existing objects in the new List.
So instead of, create a new nested ArrayList for each cloned sublist and create new Ship objects as you add elements in the new Lists.
You could define a copy constructor in Ship for example :
public Ship(Ship model){
foo = model.foo;
bar = model.bar;
}
You can so write :
for(List<Ship> list : theSea){
List<Ship> currentList = new ArrayList<>();
for(Ship ship : list){
currentList.add(new Ship(ship));
}
clone.add(currentList);
}
Assuming Ship objects are cloneable:
List<List<Ship>> clone = theSea.stream()
.map(l -> l.stream().map(s -> (Ship)s.clone()).collect(toList()))
.collect(toList());
Something like:
ArrayList<ArrayList<Ship>> listCopy = new ArrayList<>();
for (int i=0; i<list.size(); i++) {
ArrayList<Ship> newList = new ArrayList<>();
for (int j=0; j<list.get(i).size(); j++) {
newList.add(new Ship(list.get(i).get(j)));
}
listCopy.add(newList);
}
Observe this line: newList.add(new Ship(list.get(i).get(j)));
Where you need to pass the object to the constructor and from there duplicate all the attributes, otherwise you will just create a reference to the same class.
If your ship class is to complex with many other objects inside this task may be difficult and you can use a tool like serializing to json and then revert back to object or using a java deep object cloner.
I have an array of ArrayLists. I'm iterating over them using a variable called 'al' and changing the contents of that arraylist. However, I see that the contents of the original array of ArrayList have changed. Why is this?
I was expecting that since I am only changing the contents of a new variable called 'al', the contents of the original array of ArrayLists, ie alal wouldn't change.
Are these operating on memory directly? What is this concept called, if I would like to read a bit more about it.
package proj;
import java.util.ArrayList;
public class Ask
{
public static void main(String[] args)
{
ArrayList<Integer> myArrayList1 = new ArrayList<Integer>();
myArrayList1.add(1);
myArrayList1.add(1);
myArrayList1.add(1);
ArrayList<Integer> myArrayList2 = new ArrayList<Integer>();
myArrayList2.add(2);
myArrayList2.add(2);
myArrayList2.add(2);
ArrayList<ArrayList<Integer>> alal = new ArrayList<ArrayList<Integer>>();
alal.add(myArrayList1);
alal.add(myArrayList2);
for(ArrayList<Integer> al : alal)
{
al.set(0, 99);
}
System.out.println(alal);
}
}
EDIT : I'm trying to edit my code based on SMA's post so that my contents still remain the same even upon using the set method. This is what I have tried, but my output still reflects the change [[99, 1, 1], [99, 2, 2]]
package proj;
import java.util.ArrayList;
public class Ask
{
public static void main(String[] args)
{
ArrayList<Integer> myArrayList1 = new ArrayList<Integer>();
myArrayList1.add(1);
myArrayList1.add(1);
myArrayList1.add(1);
ArrayList<Integer> myArrayList2 = new ArrayList<Integer>();
myArrayList2.add(2);
myArrayList2.add(2);
myArrayList2.add(2);
ArrayList<ArrayList<Integer>> alal = new ArrayList<ArrayList<Integer>>();
alal.add(new ArrayList<Integer>(myArrayList1));//creating seperate instance of array list with same content as original list
alal.add(new ArrayList<Integer>(myArrayList2));
for(ArrayList<Integer> al : alal)
{
al.set(0, 99);
}
System.out.println(alal);
}
}
EDIT 2 : However, I don't see the same behavior in a normal ArrayList. Here the contents remain as [1, 2, 3] even after editing them to 99 inside the loop. So, are new instances of these variables created here? Aren't they mere references as before?
package proj;
import java.util.ArrayList;
public class Ask
{
public static void main(String[] args)
{
ArrayList<Integer> myArrayList = new ArrayList<Integer>();
myArrayList.add(1);
myArrayList.add(2);
myArrayList.add(3);
for(int element : myArrayList)
{
element = 99;
}
System.out.println(myArrayList);
}
}
I was expecting that since I am only changing the contents of a new variable called 'al'
alal contains references to ArrayLists. When you iterate over those ArrayLists, you are not creating new ArrayList objects. Therefore, any change in al is reflected in alal.
When you assign the reference of an existing object to a new reference variable (as you do in your for loop), you are not creating a new object. The new variable (al is your case) merely refers to the existing object.
If you wish to iterate over alal without changing the ArrayLists in contains, you must either create a copy of alal containing copies of the original ArrayLists, or use a different loop to iterate over alal while creating copies :
for (int i = 0; i < alal.length; i++) {
ArrayLst<Integer> al = new ArrayList<Integer>(alal.get(i)); // create copy
al.set(0, 99);
}
Of course, this loop doesn't make much sense, since you are modifying ArrayLists that will never be used anywhere. I'm assuming that in your real code you are doing something with the modified ArrayLists.
You are just using the same reference (reference within heap) of an array list with alal as the original one myArrayList1 and myArrayList2 and hence it acts on the same list and modifies the 0th index element.
If you don't want loop impacting original list, you should do something like:
ArrayList<ArrayList<Integer>> alal = new ArrayList<ArrayList<Integer>>();
alal.add(new ArrayList<Integer>(myArrayList1));//creating seperate instance of array list with same content as original list
alal.add(new ArrayList<Integer>(myArrayList2));
Hello im rather stuck on this part of my java programming work. I have done what i think is right for this question but im unsure if it is right as the next question asks to add 4 different strings into two different sub-lists (and thats where im getting stuk).
This is the first question:
Create a variable called balancedThings of type ArrayList of ArrayLists of Strings and add a method balancedInit() that instantiates the balancedThings variable by creating a new ArrayList > object and that also creates two new ArrayList objects and adds these to the balancedThings list.
this is the second question:
Add a method balancedCreation() that adds the strings “sword” and “map” to the first of the two sub-lists, and the strings “shield” and “bottle” to the second sub-list.
This is my answer:
void balancedInit()
{
balancedThings = new ArrayList<>();
balancedThings.add(0, "SubListOne");
balancedThings.add(1, "SubListTwo");
}
Can anyone explain if this is right for the question and where i should go next in order to add into sublists?
I think you just need to build the solution from the bottom up. Before worrying about the list of lists, worry about the individual lists first.
So first, you just want a list of strings. You can do that like this:
private static ArrayList<String> firstSublist() {
ArrayList<String> list = new ArrayList<>();
list.add("sword");
list.add("map");
return list;
}
ArrayList is your list, and the String in angle brackets tells you what type is going to be in the list. Then you add the actual strings. Do this for the other sublist too.
Then when you have a way to make your little lists, time to compose the big one:
private static void balancedCreation(ArrayList<ArrayList<String>> listOfLists) {
listOfLists.add((firstSublist()));
listOfLists.add((secondSublist()));
}
Here you have a list of lists. I know all the angle brackets can be confusing with something like ArrayList<ArrayList<String>>, but just remember to look at it a little at a time from the inside out.
So with the big list, you are just adding a thing--exactly like the sublists. As long as you take care of business at the simpler level, building up to the top level is no sweat.
In the end, main looks like this
public static void main(String[] args) {
ArrayList<ArrayList<String>> listOfLists = new ArrayList<>();
balancedCreation(listOfLists);
}
Hope this helps.
you want to add an ArrayList of Strings in an ArrayList :
public void balancedInit() {
ArrayList<ArrayList<String>> balancedThings = new ArrayList<ArrayList<String>>();
ArrayList<String> subListOne = new ArrayList<String>();
ArrayList<String> subListTwo = new ArrayList<String>();
// add values to your Sub Lists then ...
balancedThings.add(subListOne); // this will be index 0 implicitly
balancedThings.add(subListTwo); // this will be index 1 implicitly
}
programmers prefer using polymorphism in Collections framework, like declaring the ArrayList as List, but this is not a good practice when it comes to Serialization
initialize andinstantiate the "SublistOne" and "SubListTwo" in the way you initialized the BalancedThings.
that should create the sublist.
void balancedInit()
{
ArrayList<ArrayList<String>> balancedThings = new ArrayList<ArrayList<String>>();
ArrayList<String> subLiostOne = = new ArrayList<String>();
ArrayList<String> subLiostTwo = = new ArrayList<String>();
subListOne.add(0,"sword");
subListOne.add(1,"map");
subListTwo.add(0,"shield");
subListTwo.add(1,"bottle");
balancedThings.add(0, subListOne);
balancedThings.add(1, subListTwo);
}
please mark the answer as helpful if it is helpful
I am implementing a Java class responsible for ordering java.util.List. The problem comes when I use this class. I'm able to ordering the list but I want to copy the "original" list without modification so that I could register every change made on the original list. The sorted list contains object and one of its fields stores a classification id, and this id it is updated with the index value of the list.
I tried to use clone method and it keeps the list unsorted but the changes made on original list are updated in the clone list too.
Is there any way to accomplish it?
My Code:
List<Torero> listaTorero = tbTlgTorerolHome.findByExample(new Torero());
List<Torero> listaToreroTemp = ((List<Torero>) ((ArrayList<Torero>) listaTorero).clone());
Clasificacion clasificacion = new Clasificacion();
Iterator<Torero> iterTorero = clasificacion.getClasificacion(listaTorero, torero).iterator(); //Sorting List
A Clasificacion method:
public List<Torero> getClasificacion(List<Torero> listaToreroTemp, Torero torero)
{
List<Torero> listaTorero = new ArrayList<Torero>();
Collections.sort(listaToreroTemp,new ToreroClasifiacionComparator());
Iterator<Torero> iterTorero = listaToreroTemp.iterator();
int index=1;
while(iterTorero.hasNext())
{
Torero toreroTemp = iterTorero.next();
toreroTemp.setNumClasificacion(index);
listaTorero.add(toreroTemp);
index=index+1;
}
return listaTorero;
}
You may create a new list with an input of a previous list like so:
List one = new ArrayList()
//... add data, sort, etc
List two = new ArrayList(one);
This will allow you to modify the order or what elemtents are contained independent of the first list.
Keep in mind that the two lists will contain the same objects though, so if you modify an object in List two, the same object will be modified in list one.
example:
MyObject value1 = one.get(0);
MyObject value2 = two.get(0);
value1 == value2 //true
value1.setName("hello");
value2.getName(); //returns "hello"
Edit
To avoid this you need a deep copy of each element in the list like so:
List<Torero> one = new ArrayList<Torero>();
//add elements
List<Torero> two = new Arraylist<Torero>();
for(Torero t : one){
Torero copy = deepCopy(t);
two.add(copy);
}
with copy like the following:
public Torero deepCopy(Torero input){
Torero copy = new Torero();
copy.setValue(input.getValue());//.. copy primitives, deep copy objects again
return copy;
}
Use the ArrayList copy constructor, then sort that.
List oldList;
List newList = new ArrayList(oldList);
Collections.sort(newList);
After making the copy, any changes to newList do not affect oldList.
Note however that only the references are copied, so the two lists share the same objects, so changes made to elements of one list affect the elements of the other.
I am wanting to create an array of arraylist like below:
ArrayList<Individual>[] group = new ArrayList<Individual>()[4];
But it's not compiling. How can I do this?
As per Oracle Documentation:
"You cannot create arrays of parameterized types"
Instead, you could do:
ArrayList<ArrayList<Individual>> group = new ArrayList<ArrayList<Individual>>(4);
As suggested by Tom Hawting - tackline, it is even better to do:
List<List<Individual>> group = new ArrayList<List<Individual>>(4);
As the others have mentioned it's probably better to use another List to store the ArrayList in but if you have to use an array:
ArrayList<Individual>[] group = (ArrayList<Individual>[]) new ArrayList[4];
You will need to suppress the warning but it's safe in this case.
This works:
ArrayList<String>[] group = new ArrayList[4];
Though it will produce a warning that you may want to suppress.
You can create a class extending ArrayList
class IndividualList extends ArrayList<Individual> {
}
and then create the array
IndividualList[] group = new IndividualList[10];
You can create Array of ArrayList
List<Integer>[] outer = new List[number];
for (int i = 0; i < number; i++) {
outer[i] = new ArrayList<>();
}
This will be helpful in scenarios like this. You know the size of the outer one. But the size of inner ones varies. Here you can create an array of fixed length which contains size-varying Array lists. Hope this will be helpful for you.
In Java 8 and above you can do it in a much better way.
List<Integer>[] outer = new List[number];
Arrays.setAll(outer, element -> new ArrayList<>());
This works, array of ArrayList. Give it a try to understand how it works.
import java.util.*;
public class ArrayOfArrayList {
public static void main(String[] args) {
// Put the length of the array you need
ArrayList<String>[] group = new ArrayList[15];
for (int x = 0; x < group.length; x++) {
group[x] = new ArrayList<>();
}
//Add some thing to first array
group[0].add("Some");
group[0].add("Code");
//Add some thing to Secondarray
group[1].add("In here");
//Try to output 'em
System.out.println(group[0]);
System.out.println(group[1]);
}
}
Credits to Kelvincer for some of codes.
The problem with this situation is by using a arraylist you get a time complexity of o(n) for adding at a specific position. If you use an array you create a memory location by declaring your array therefore it is constant
You can't create array of generic type. Create List of ArrayLists :
List<ArrayList<Individual>> group = new ArrayList<ArrayList<Individual>>();
or if you REALLY need array (WARNING: bad design!):
ArrayList[] group = new ArrayList[4];
Creation and initialization
Object[] yourArray = new Object[ARRAY_LENGTH];
Write access
yourArray[i]= someArrayList;
to access elements of internal ArrayList:
((ArrayList<YourType>) yourArray[i]).add(elementOfYourType); //or other method
Read access
to read array element i as an ArrayList use type casting:
someElement= (ArrayList<YourType>) yourArray[i];
for array element i: to read ArrayList element at index j
arrayListElement= ((ArrayList<YourType>) yourArray[i]).get(j);
List[] listArr = new ArrayList[4];
Above line gives warning , but it works (i.e it creates Array of ArrayList)
To declare an array of ArrayLists statically for, say, sprite positions as Points:
ArrayList<Point>[] positionList = new ArrayList[2];
public Main(---) {
positionList[0] = new ArrayList<Point>(); // Important, or you will get a NullPointerException at runtime
positionList[1] = new ArrayList<Point>();
}
dynamically:
ArrayList<Point>[] positionList;
int numberOfLists;
public Main(---) {
numberOfLists = 2;
positionList = new ArrayList[numberOfLists];
for(int i = 0; i < numberOfLists; i++) {
positionList[i] = new ArrayList<Point>();
}
}
Despite the cautions and some complex suggestions here, I have found an array of ArrayLists to be an elegant solution to represent related ArrayLists of the same type.
ArrayList<String>[] lists = (ArrayList<String>[])new ArrayList[10];
You can create like this
ArrayList<Individual>[] group = (ArrayList<Individual>[])new ArrayList[4];
You have to create array of non generic type and then cast it into generic one.
ArrayList<Integer>[] graph = new ArrayList[numCourses]
It works.
I think I'm quite late but I ran into the same problem and had to create an array of arraylists as requested by my project in order to store objects of different subclasses in the same place and here is what I ended up doing:
ArrayList<?>[] items = new ArrayList[4];
ArrayList<Chocolate> choc = new ArrayList<>();
ArrayList<Chips> chips = new ArrayList<>();
ArrayList<Water> water = new ArrayList<>();
ArrayList<SoftDrink> sd = new ArrayList<>();
since each arraylist in the array would contain different objects (Chocolate , Chips , Water and SoftDrink )
--it is a project to simulate a vending machine--.
I then assigned each of the Arraylists to an index of the array:
items[0]=choc;
items[1]=chips;
items[2]=water;
items[3]=sd;
Hope that helps if anyone runs into a similar issue.
I find this easier to use...
static ArrayList<Individual> group[];
......
void initializeGroup(int size)
{
group=new ArrayList[size];
for(int i=0;i<size;i++)
{
group[i]=new ArrayList<Individual>();
}
You can do thi. Create an Array of type ArrayList
ArrayList<Integer>[] a = new ArrayList[n];
For each element in array make an ArrayList
for(int i = 0; i < n; i++){
a[i] = new ArrayList<Integer>();
}
If you want to avoid Java warnings, and still have an array of ArrayList, you can abstract the ArrayList into a class, like this:
public class Individuals {
private ArrayList<Individual> individuals;
public Individuals() {
this.individuals = new ArrayList<>();
}
public ArrayList<Individual> getIndividuals() {
return individuals;
}
}
Then you can safely have:
Individuals[] group = new Individuals[4];
ArrayList<String> al[] = new ArrayList[n+1];
for(int i = 0;i<n;i++){
al[i] = new ArrayList<String>();
}
you can create a List[] and initialize them by for loop. it compiles without errors:
List<e>[] l;
for(int i = 0; i < l.length; i++){
l[i] = new ArrayList<e>();
}
it works with arrayList[] l as well.