I have an ArrayList of ArrayList like the following code and I'm intended to add one item to an existed arraylist and save it as well as keeping the old arrayList.
ArrayList<ArrayList<Integer>> bigArr = new ArrayList<ArrayList<Integer>> ();
ArrayList<Integer> arr = new ArrayList<Integer> ();
arr.add(1);
arr.add(2);
arr.add(3);
bigArr.add(arr);
ArrayList<Integer> tt = bigArr.get(0);
tt.add(4);
bigArr.add(tt);
System.out.println(bigArr);
But the thing is that happens is that it prints [[1, 2, 3, 4], [1, 2, 3, 4]] instead of [[1, 2, 3], [1, 2, 3, 4]]. Can someone please tell me what should I do to get the second output?
Create two lists instead of reusing the first list.
ArrayList<ArrayList<Integer>> bigArr = new ArrayList<ArrayList<Integer>> ();
ArrayList<Integer> arr = new ArrayList<Integer> ();
arr.add(1);
arr.add(2);
arr.add(3);
bigArr.add(arr);
ArrayList<Integer> tt = new ArrayList<Integer>(arr); // Create a new list based on the elements of the given list
tt.add(4);
bigArr.add(tt);
System.out.println(bigArr);
Object type parameter's references are pass by value but the
memory location that is pointed by them remains same. So changing anything using any reference variable will affect the same
Object.
So here tt and arr is pointing to the same memory location means if you change something in one of them that gets reflected to other as well.
Because your tt is still pointing to the same arraylist object. It's modifying the same object.
Solution: Make a new list object by copying old list and add item in that list then add list to main list.
Lists are objects with mutable state. This means that adding or removing items will change the state of the List your variable is pointing to. You create a single arr = ArrayList<Integer>, to which you add the values 1, 2, 3. You then add this list to the bigArr list of lists. Now, the first element of bigArr and arr both point to the same physical object. The moment you retrieve it from bigArr and store it in the tt variable, you have three ways to access the same list.
What you want, is a new version (copy) of your initial list at bigArr.get(0) and add the new value to that list. The easiest way to do this is to use ArrayList's copy constructor when you retrieve it from the bigArr. This is already explained in the answer given by Smutje:
ArrayList<Integer> tt = new ArrayList<Integer> (arr);
Related
I am trying to create a copy to an Array List of Array Lists, but when doing so the addresses of all the individual elements are staying the same.
copySorted = new ArrayList<ArrayList<String>>(origSorted);
I would expect to generate a copy of origSorted without references to the original, but instead whenever I make a change to copySorted, it ends up happening to origSorted as well. I also tried the .clone() function with the same results.
It's not the changes to copySorted you're seeing, it's changes to the inner lists which are shared between the outer lists. If you want them to be completely distinct, you'll need to copy each one individually:
copySorted = new ArrayList<>(origSorted.size());
for (List<String> inner : origSorted) {
copySorted.add(new ArrayList<>(inner));
}
Firstly you creat your ArrayList then creat your new arrayList by using the keyWord "new" so the new arraylist will be a new object seprate from the first arraylist like this:
ArrayList<String> myFirstArrayList = new ArrayList<>();//creat my first arrayList
//add some objects
myFirstArrayList.add("1");
myFirstArrayList.add("2");
myFirstArrayList.add("3");
//print it
System.out.println(myFirstArrayList);//[1, 2, 3]
//creating a new arrayList by coping the first but we create a new arrayList by using the keyword "New"
ArrayList<String> newArrayList= new ArrayList<>(myFirstArrayList);
//print new arraylist
System.out.println(newArrayList);//[1, 2, 3]
//make some change in the new arraylist
newArrayList.remove(1);
//print the
System.out.println(newArrayList);//[1, 3]
System.out.println(myFirstArrayList);//[1, 2, 3]
//my original arraylist still not changed b'z the two objects of arraylists are seperate.
I have a problem with pulling out a value from an Arraylist inside an Arraylist.
I'll just give an example of my problem.
Example:
ArrayList alA = new ArrayList();
ArrayList alB = new ArrayList();
alA.add("1");
alA.add("2");
alA.add("3");
alB.add(alA);
System.out.println(alB.get(0));
This will return [1, 2, 3] as the result.
In my case I only need to print out 3. How do I achieve this?
Just call get on the inner array:
System.out.println(((List) alB.get(0)).get(2));
Note that by using generics, you'll eliminate the need to cast:
List<String> alA = new ArrayList<>();
List<List<String>> alB = new ArrayList<>();
alA.add("1");
alA.add("2");
alA.add("3");
alB.add(alA);
System.out.println(alB.get(0).get(2));
Simply do the following if you don't want to change your other portions of current code
System.out.println(((ArrayList)alB.get(0)).get(2));
System.out.println(alB.get(0)); return alB's 0th index element which is alA. Since you want the element 3, you need to get the 2nd index element of alA, in this case it is alA.get(2);
Combined:
System.out.println(((ArrayList)alB.get(0)).get(2));
What the difference between assigning an arraylist to another and using method addAll between two arraylists?
1 > arrayList = arrayList; //should assign value of later arrayList to the first.
2> arrayList.addAll(arrayList) //add all the data of the later list to first.
the first completely replaces the data in the list ?
the second one for appending data in the list(if it already has any) ???
if i do arrayList.add(arrayList) without assigning any data to the first list, will it insert any data ?
I did the following code for testing and found results that i do'not really know.
secondList.add("1");
secondList.add("2");
firstList = secondList;
Log.i("CHECK","first list = "+ firstList);
firstList.addAll(secondList);
Log.i("CHECK","Firs list add : "+firstList);
firstList.clear();
firstList.addAll(secondList);
Log.i("CHECK","Firs list add 2 : "+firstList);
Result were :
CHECK: first list = [1, 2]
CHECK: Firs list add : [1, 2, 1, 2]
CHECK: Firs list add 2 : []
i was expecting the last log to have result like : [1,2]
as mentioned in docs.oracle.com
addAll- Appends all of the elements in the specified collection to the
end of this list, in the order that they are returned by the specified
collection's Iterator.
and if there's no data in the list ? then what will addAll DO ?
When you do:
firstList = secondList;
What you are saying is actually "to make firstList and secondList refer to the same list". After the line is executed, there will only be one list and two variables both refer to that list.
This is why after you cleared firstList, secondList lost all the elements as well. They refer to the same thing. This has nothing to do with addAll. When you called firstList.addAll(secondList), you are basically adding appending an empty list to another empty list, which results in an empty list.
when you use arrayList = arrayList2; then you are assigning the reference of arrayList2 in first list. That means they are referring to the same list.
and when you use arrayList.addAll(arrayList2) then they are two different list reference.
Now come back to your code (lets denote firstlist as f, second as s)
secondList.add("1"); // f={}, s = {1}
secondList.add("2"); // f={}, s = {1,2}
firstList = secondList; // f= s = {1, 2}
Log.i("CHECK","first list = "+ firstList); // so printing 1,2
firstList.addAll(secondList);// it is actually adding itself.. so f= s = {1,2,1,2}
Log.i("CHECK","Firs list add : "+firstList);
firstList.clear(); // clear boths as s = f
firstList.addAll(secondList); // as boths are blank so overall blank
Log.i("CHECK","Firs list add 2 : "+firstList);
I learned about this in class, Java doesnt really specify when it passes by value or passes by reference, but for the sake of arrayList's, they are pass by reference unless you specifically create new elements. When you say
firstArray = secondArray;
firstArray gets the memory address of the second array, therefore when you cleared the first array, you actually cleared the memory which the second array also shares.
Good luck!
Conceptually what is going on here?
I have an ArrayList
ArrayList<SomeClass> myArray = new ArrayList<SomeClass>();
then I add something to it like this
myArray.add(new myArray(1, 2, 3));
I have an array
ArrayList myArray = new ArrayList();
No, you don't have an array. Arrays are declared using brackes [], like this:
int[] myArray;
You have an object of ArrayList class. This object will use an array internally to store the data and dynamically change the array for a newer one when needs to assign more values.
then I add something to it like this
myArray.add(new myArray(1, 2, 3));
Conceptually, this is wrong and won't even compile. If you want to add more than one value in your array, you should use ArrayList#addAll method, that receives another collection. Then, you have two ways to pass a Collection in one statement:
Create a list using Arrays#asList:
myArray.addAll(Arrays.asList(1, 2, 3));
You can use double brace initialization:
myArray.addAll(new ArrayList() {{
add(1);
add(2);
add(3);
}});
You should take into account that you should specify the generic for your ArrayList instead of using raw data:
ArrayList<Integer> myArray = new ArrayList<Integer>();
myArray.addAll(new ArrayList<Integer>() {{
add(1);
add(2);
add(3);
}});
More info:
Java Tutorial. Collections
Initialization of an ArrayList in one line
Note that if you have an ArrayList that is tied to a custom class, let's say ArrayList<SomeClass> myArrayList, then the compiler prevents you to add elements to the list that doesn't pass the IS-A test (noted by instanceof operator), so this code:
ArrayList<SomeClass> myArrayList = new ArrayList<SomeClass>();
myArrayList..addAll(new ArrayList<Integer>() {{
add(1);
add(2);
add(3);
}});
Won't be able to compile since Integer is not a SomeClass. Similar with this piece of code:
ArrayList<SomeClass> myArrayList = new ArrayList<SomeClass>();
myArray.add(Arrays.asList(1, 2, 3));
But due to type erasure you can trick the compiler by using raw types. For example:
public void addData(ArrayList yourArrayList, Object anyData) {
yourArrayList.add(anyData);
}
Then in your code, you call this method:
ArrayList<String> myArrayList = new ArrayList<String>(); //allows Strings only
myArrayList.add("Hello world");
//myArrayList.add(0); //this won't compile because trying to add an Integer
addData(myArrayList, 0); //this will compile for using raw ArrayList and sending an Integer
System.out.println(myArrayList);
It will print:
[Hello world, 0]
myArray.add(new myArray(1, 2, 3));
This is not correct and don't compile, cause myArray is not a type, it's just a reference, you need something of type integer or if you want to add another list, then use addAll.
You could use something like this.
List<Integer> myArray = new ArrayList<>(); // specify with generics type parameter
//do some things and then
myArray.addAll(Arrays.asList(1,2,3)); // use this helper method to add a list to another list
Or if you want to only create and populate it, just use
List<Integer> myArray = Arrays.asList(1,2,3,4,5);
I think I know what you're trying to do, say you have this.
ArrayList<Integer[]> myArray = new ArrayList<Integer[]>();
and you wanted to add an array to it, you're basically going to call
myArray.add(((Integer[]) new int[] { 0, 1, 2 }));
Which will add the array [0, 1, 2] to the next index in the ArrayList.
For exmaple, the following code
ArrayList<Integer[]> myArray = new ArrayList<Integer[]>();
myArray.add(((Integer[]) new int[] { 0, 1, 2 }));
myArray.add(((Integer[]) new int[] { 1, 0, 2 }));
myArray.add(((Integer[]) new int[] { 3, 2, 1 }));
Would create the following results:
myArray index 0 = [0, 1, 2]
myArray index 1 = [1, 0, 2]
myArray index 2 = [3, 2, 1]
Is this your question?
You don't actually have an array, you have an ArrayList. An ArrayList is a resizable implementation of the List interface. This means, among other things, that you don't have to define a length like you would with an array.
I don't think the code you have provided will actually compile because when you go:
myArray.add(new myArray(1, 2, 3));
you haven't provided a type. You should go something like:
myArray.add(new ArrayList<Integer>(Arrays.asList(1,2,3)));
Using asList() will give almost the equivalent of assigning "default" values to an array. The array equivalent would look something like this:
Integer[] intArray = new Integer[] {1,2,3};
You should also parameterize your ArrayList(s), this basically means you are saying what that ArrayList can hold. For instance:
ArrayList<Integer>
Can hold Integers.
The reason you must use a wrapper class (Integer & not int) is because Collections in Java don't permit you to store primitive types such as int or double.
You can have a Collection holding another Collection. In this case you could go:
ArrayList<ArrayList<Integer>> myArrayList = new ArrayList<ArrayList<Integer>>();
myArrayList.add(new ArrayList<Integer>(Arrays.asList(1, 2, 3)));
myArrayList.add(new ArrayList<Integer>(Arrays.asList(9, 12, 24)));
for (ArrayList<Integer> index : myArrayList) {
System.out.println(index);
}
Here you have an ArrayList holding two other ArrayLists. This results in the printing of:
[1, 2, 3]
[9, 12, 24]
My arraylist might be populated differently based on a user setting, so I've initialized it with
ArrayList<Integer> arList = new ArrayList<Integer>();
How can I add hundreds of integers without doing it one by one with arList.add(55);?
If you have another list that contains all the items you would like to add you can do arList.addAll(otherList). Alternatively, if you will always add the same elements to the list you could create a new list that is initialized to contain all your values and use the addAll() method, with something like
Integer[] otherList = new Integer[] {1, 2, 3, 4, 5};
arList.addAll(Arrays.asList(otherList));
or, if you don't want to create that unnecessary array:
arList.addAll(Arrays.asList(1, 2, 3, 4, 5));
Otherwise you will have to have some sort of loop that adds the values to the list individually.
What is the "source" of those integers? If it is something that you need to hard code in your source code, you may do
arList.addAll(Arrays.asList(1,1,2,3,5,8,13,21));
Collections.addAll is a varargs method which allows us to add any number of items to a collection in a single statement:
List<Integer> list = new ArrayList<>();
Collections.addAll(list, 1, 2, 3, 4, 5);
It can also be used to add array elements to a collection:
Integer[] arr = ...;
Collections.addAll(list, arr);
If you are looking to avoid multiple code lines to save space, maybe this syntax could be useful:
java.util.ArrayList lisFieldNames = new ArrayList() {
{
add("value1");
add("value2");
}
};
Removing new lines, you can show it compressed as:
java.util.ArrayList lisFieldNames = new ArrayList() {
{
add("value1"); add("value2"); (...);
}
};
Java 9+ now allows this:
List<Integer> arList = List.of(1,2,3,4,5);
The list will be immutable though.
In a Kotlin way;
val arList = ArrayList<String>()
arList.addAll(listOf(1,2,3,4,5))
If you needed to add a lot of integers it'd probably be easiest to use a for loop. For example, adding 28 days to a daysInFebruary array.
ArrayList<Integer> daysInFebruary = new ArrayList<>();
for(int i = 1; i <= 28; i++) {
daysInFebruary.add(i);
}
I believe scaevity's answer is incorrect. The proper way to initialize with multiple values would be this...
int[] otherList = {1,2,3,4,5};
So the full answer with the proper initialization would look like this
int[] otherList = {1,2,3,4,5};
arList.addAll(Arrays.asList(otherList));