Add List to List<List<>> collections in java [duplicate] - java

This question already has answers here:
Java ArrayList of ArrayList
(4 answers)
Closed 6 years ago.
List<List<Integer>> list = new LinkedList<List<Integer>>();
List<Integer> tmp = new LinkedList<Integer>();
tmp.add(2);
list.add(tmp);
tmp.add(3);
list.add(tmp);
The result of list is [[2,3],[2,3]]; I just confused about that why it is not [[2],[2,3]]. And when I use list.add(new LinkedList<Integer>(tmp)) it will work. I print tmp, it is still [2], [2,3], it is not changed. Why that happen?
Thank you in advance.

You added a reference to tmp to list. When you added it, tmp only contained [2,3]. After the addition to list, you added 3 to the same reference of tmp. This caused both "copies" to have [2,3].
One way could be to create a new list and do the following
tmp = new LinkedList<Integer>();
tmp.add(3);
list.add(tmp);
Now, list will look like [[2],[3]].
If you want list to be [[2],[2,3]]...
List<List<Integer>> list = new LinkedList<List<Integer>>();
List<Integer> tmp = new LinkedList<Integer>();
tmp.add(2);
// add a copy of this linkedlist to the "BIG" list
list.add(new LinkedList<Integer>(tmp));
tmp.add(3);
list.add(tmp);
let me know if something is not clear.

Java uses references to objects that you create with new to refer to those objects. In this example, the variable tmp is actually a reference to the LinkedList object on the heap.
Since list is a list of objects, it is actually a list of references to those objects. In this case, its two elements are references to the same heap object, tmp.

Related

How to build an array of ArrayList<Integer> in Java? [duplicate]

This question already has answers here:
How can I create an Array of ArrayLists?
(20 answers)
Closed 5 years ago.
I wrote a piece of code like this
ArrayList<Integer>[]list=new ArrayList<Integer>[128];
But Eclipse says
Cannot create a generic array of ArrayList
I also tried code like this
ArrayList<Integer>[]list=(ArrayList<Integer>[])new Object[128];
But Eclipse throws exception:
[Ljava.lang.Object; cannot be cast to [Ljava.util.ArrayList;
So how can I build an array of ArrayList< Integer > ?
Thanks a lot!!
List<Integer> inp = new ArrayList<Integer>(10) to create list of integers whose size is 10.
From what I see you are trying to create an ArrayList and an Array in the same step, which is impossible.
An Arraylist differs from arrays as it is a generic class, which means it has a lot more functionality.
For example:
In your code you are trying to specify a limit to the ArrayList, ArrayLists don't have a limit, they are expandable.
You can use the .add() function to add objects to ArrayLists, and get values using the .get(int index) function.
Example code:
ArrayList<Integer> myArray = new ArrayList<Integer>(); //initialized a new arrayList
myArray.add(7); //added element 7 at index 0
myArray.add(12); // added element 12 at index 1
print(myArray.get(1)) //output 12
You can check the documentations for the ArrayList class here.
Hope that helped.
Your question isn't really clear,
but to build an array list,this code should be sufficient
ArrayList<Integer> list;
list = new ArrayList<Integer>(128);
Use this to create an ArrayList (remember, ArrayLists always have a theoretically indefinite capacity, since you can always add more elements to them - see a tutorial):
ArrayList<Integer> list = new ArrayList<>();
or this to make an array of ArrayLists:
ArrayList<Integer>[] lists = new ArrayList[128];
You will of course have to initialize your ArrayLists:
for (int i = 0; i < lists.length; i++)
lists[i] = new ArrayList<>();
Alternatively, you can create an ArrayList of ArrayLists:
ArrayList<ArrayList<Integer>> lists2 = new ArrayList<>();
for (int i = 0; i < 128; i++)
lists2.add(new ArrayList<>());

Own Shuffle Method Doesn't Work in Java [duplicate]

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 8 years ago.
I have created simple shuffle method everyting seems okay but there is a problem which i can't find.
Here is my Code Below:
public static <E> void shuffle(List<? extends E> list) {
List<E> temp = new ArrayList<>();
while (list.size() != 0) {
E val = list.remove((int) (Math.random() * list.size()));
temp.add(val);
System.out.println(val);
}
System.out.println(temp);
list = temp;
}
This is the test case:
ArrayList<Integer> arr = new ArrayList<>();
arr.add(1);
arr.add(2);
arr.add(3);
arr.add(4);
arr.add(5);
arr.add(6);
System.out.println(arr);
shuffle(arr);
System.out.println("-->" + arr);
The problem is last print out method shows that arr is empty --> [] It Should be something like that [4,3,1,2,6,5]
Problem could be this line but i did not understand why ?
--> list = temp;
Yes, it's this line:
list = temp;
All that does is copy the temp reference to the list reference. Now, both list and temp refer to your local list originally referred to by temp.
You'll want to add the contents of temp back to list instead.
list.addAll(temp);
list = temp just assigns a new value (the contents of temp) to the local variable named list - it does not change the object that list originally pointed to.
If you want to achieve such functionality, you could just re-add all the items in temp to list (after the while loop concludes, so you know it's empty):
list.addAll(temp);
The shuffle method receives a copy of a reference to your list. When you do list = temp; you're telling that reference to point to temp.
So you basically empty the list that is passed to the method and then you lose access to it.

Copying arraylist

I think doing arraylist1=arraylist2 makes the 2 of them share the same memory. How can I copy an arraylist without them doing that? I want to treat them sepparately.
List<Integer> rez = new ArrayList<>();
List<Integer> rezc = new ArrayList<>();
rez.add(1);
rezc=rez;
rezc.add(2);
for (int s : rez) {
System.out.print(s + " ");
}//this will print 1 2
I think doing arraylist1=arraylist2 makes the 2 of them share the same memory.
Not quite, it makes both of those references refer to the same, single, object.
How can I copy an arraylist without them doing that?
Lots of options:
ArrayList has a copy constructor:
List<Integer> rezc = new ArrayList<>(rez);
List has an addAll method:
List<Integer> rezc = new ArrayList<>();
rezc.addAll(rez);
ArrayList has a clone method, but it's a bit ugly to use if rez is declared as a List because you have to assume it's an ArrayList and cast it, which is probably not a great idea:
List<Integer> rezc = (List<Integer>)((ArrayList<Integer>)rez).clone();
It's well worth reading through the JavaDoc when trying to figure things like this out.
The statement arraylist1=arraylist2 means they are referring to same ArrayList object. Reference variables arraylist1 and arraylist2 are referring to same object and hence, the changes done by arraylist1 will be seen when you are trying to access the object by arraylist2
If you want to make a new ArrayList then, ArrayList rezc = new ArrayList(rez)
Instead of this line rezc=rez;
Use List<Integer> rezc = new ArrayList<>(rez);
The long hand way is a for loop to cycle though one list while adding all the items to the second. Something like
for (int I = 0; I < rez.size() I++) {
rezc.add(rez.get(I)); }
But the previous answers are much more efficient.
If I understand correctly you are talking about Java shallow cloning v/s deep cloning. In this case the below code might help
List<Integer> rez = new ArrayList<>();
List<Integer> rezc = new ArrayList<>();
rez.add(1);
rezc.addAll(rez); // addAll
List<Integer> rezc2 = (List<Integer>)((ArrayList<Integer>)rez).clone(); //clone

calling remove(int) method for an arraylist removes the item from all similar arraylists

Okey, I'm not a professional programmer so my question might sound silly.
I have this code:
ArrayList<Integer> list1 = new ArrayList<Integer>();
list1 = list2;
Please take note that list2 has three items inside [1, 2, 4]. So now, list1 has the same items inside.
But when I call remove(index) method. It removes that item from both ArrayLists.
This is my complete code:
ArrayList<Integer> list1 = new ArrayList<Integer>();
list1 = list2;
for (int i = 0; i < list1.size(); i++) {
if (list1.get(i) == practiceId) {
list1.remove(i);
}
}
The purpose I'm doing this is to solve a problem which has other solutions. I'm asking this question just because I'm curious and would like to know why this happens? And how would one remove an item without removing from both ArrayLists?
Also, I have some ideas why this is happening. When I tried debugging the code step-by-step, it shows that the both ArrayLists have the same id. So I thought this might be the cause of the problem. If this is true, then is there a way to make a new ArrayList and put all items inside other ArrayList in the new one without having to add all items one by one?
So when you set those two lists equal to each other I don't think you are doing what you think you're doing. That sounded funny. When you do it the way that you have above you are actually setting the memory address of list1 to the same as list2. So now that they both point to the same place in memory when you remove it will remove from both lists.
Make sense??
It is because ArrayList stores Objects and you are saying list1 = list2 which sets their reference the same, what you need to do is create another ArrayList called list2, so that their values but not their reference is the same, you can do this by.
list2.equals(list1);
when you are doing list1 = list2it is eventually making both object same., and while trying to delete items from one it is in terms deleting from both as both objects have same instance value.
if you want to copy items you can do as follows.
ArrayList list1 = new ArrayList();
for (int i = 0; i < list2.size(); i++) {
list1.add(list2.get(i));
}
the above code will copy list items from list2 to list1 and would be different objects now.
Now you can do operations on one list and it wont affect another list
Dont use list = list2 for copying content of arraylists. it just add a refrence to the original arraylist. For copying the content of arraylist use this:
list1.addAll(list2);
Pretty much all answers mentioned are helpful.
But as I mentioned before, I don't want to add elements one by one. There was an answer which was:
ArrayList<Integer> list1 = new ArrayList<Integer>(list2);
Which was unfortunately deleted by poster. Anyways, this is exactly what I'm looking for. Clean, one line and no need for extra methods or loops or anything.
Thanks for your answers :)
I hope this help will you
ArrayList<Integer> list1 = new ArrayList<Integer>();
ArrayList<Integer> list2 = new ArrayList<Integer>();//added 1, 2, 4
list1 = (ArrayList<Integer>) list2.clone();
When you do list2 = list1, the same reference is copied to the the second list, so whatever changes you do in one list, same will happen in other. To successfully do this, you should use this :-
list2.addAll(1);
Now, if you will remove from list2, only items will be removed from list2 and not list1

How do I copy the contents of one ArrayList into another?

I have some data structures, and I would like to use one as a temporary, and another as not temporary.
ArrayList<Object> myObject = new ArrayList<Object>();
ArrayList<Object> myTempObject = new ArrayList<Object>();
//fill myTempObject here
....
//make myObject contain the same values as myTempObject
myObject = myTempObject;
//free up memory by clearing myTempObject
myTempObject.clear();
now the problem with this of course is that myObject is really just pointing to myTempObject, and so once myTempObject is cleared, so is myObject.
How do I retain the values from myTempObject in myObject using java?
You can use such trick:
myObject = new ArrayList<Object>(myTempObject);
or use
myObject = (ArrayList<Object>)myTempObject.clone();
You can get some information about clone() method here
But you should remember, that all these ways will give you a copy of your List, not all of its elements. So if you change one of the elements in your copied List, it will also be changed in your original List.
originalArrayList.addAll(copyArrayList);
Please Note: When using the addAll() method to copy, the contents of both the array lists (originalArrayList and copyArrayList) refer to the same objects or contents. So if you modify any one of them the other will also reflect the same change.
If you don't wan't this then you need to copy each element from the originalArrayList to the copyArrayList, like using a for or while loop.
There are no implicit copies made in java via the assignment operator. Variables contain a reference value (pointer) and when you use = you're only coping that value.
In order to preserve the contents of myTempObject you would need to make a copy of it.
This can be done by creating a new ArrayList using the constructor that takes another ArrayList:
ArrayList<Object> myObject = new ArrayList<Object>(myTempObject);
Edit: As Bohemian points out in the comments below, is this what you're asking? By doing the above, both ArrayLists (myTempObject and myObject) would contain references to the same objects. If you actually want a new list that contains new copies of the objects contained in myTempObject then you would need to make a copy of each individual object in the original ArrayList
Came across this while facing the same issue myself.
Saying arraylist1 = arraylist2 sets them both to point at the same place so if you alter either the data alters and thus both lists always stay the same.
To copy values into an independent list I just used foreach to copy the contents:
ArrayList list1 = new ArrayList();
ArrayList list2 = new ArrayList();
fill list1 in whatever way you currently are.
foreach(<type> obj in list1)
{
list2.Add(obj);
}
Supopose you want to copy oldList into a new ArrayList object called newList
ArrayList<Object> newList = new ArrayList<>() ;
for (int i = 0 ; i<oldList.size();i++){
newList.add(oldList.get(i)) ;
}
These two lists are indepedant, changes to one are not reflected to the other one.
Lets try the example
ArrayList<String> firstArrayList = new ArrayList<>();
firstArrayList.add("One");
firstArrayList.add("Two");
firstArrayList.add("Three");
firstArrayList.add("Four");
firstArrayList.add("Five");
firstArrayList.add("Six");
//copy array list content into another array list
ArrayList<String> secondArrayList=new ArrayList<>();
secondArrayList.addAll(firstArrayList);
//print all the content of array list
Iterator itr = secondArrayList.iterator();
while (itr.hasNext()) {
System.out.println(itr.next());
}
In print output as below
One
Two
Three
Four
Five
Six
We can also do by using clone() method for which is used to create exact copy
for that try you can try as like
**ArrayList<String>secondArrayList = (ArrayList<String>) firstArrayList.clone();**
And then print by using iterator
**Iterator itr = secondArrayList.iterator();
while (itr.hasNext()) {
System.out.println(itr.next());
}**
You need to clone() the individual object. Constructor and other methods perform shallow copy. You may try Collections.copy method.
Straightforward way to make deep copy of original list is to add all element from one list to another list.
ArrayList<Object> originalList = new ArrayList<Object>();
ArrayList<Object> duplicateList = new ArrayList<Object>();
for(Object o : originalList) {
duplicateList.add(o);
}
Now If you make any changes to originalList it will not impact duplicateList.
to copy one list into the other list, u can use the method called
Collection.copy(myObject myTempObject).now after executing these line of code u can see all the list values in the myObject.
Copy of one list into second is quite simple , you can do that as below:-
ArrayList<List1> list1= new ArrayList<>();
ArrayList<List1> list2= new ArrayList<>();
//this will your copy your list1 into list2
list2.addAll(list1);
Here is a workaround to copy all the objects from one arrayList to another:
ArrayList<Object> myObject = new ArrayList<Object>();
ArrayList<Object> myTempObject = new ArrayList<Object>();
myObject.addAll(myTempObject.subList(0, myTempObject.size()));
subList is intended to return a List with a range of data. so you can copy the whole arrayList or part of it.
Suppose you have two arraylist of String type .
Like
ArrayList<String> firstArrayList ;//This array list is not having any data.
ArrayList<String> secondArrayList = new ArrayList<>();//Having some data.
Now we have to copy the data of second array to first arraylist like this,
firstArrayList = new ArrayList<>(secondArrayList );
Done!!
The simplest way is:
ArrayList<Object> myObject = new ArrayList<Object>();
// fill up data here
ArrayList<Object> myTempObject = new ArrayList(myObject);

Categories