I'm a beginner in Java and I'm trying to create an ArrayList that stores ArrayLists which hold integers. I already know the size I want for the outer ArrayList and want to store the inner ArrayLists. I would then for example want to add all dog ID numbers to the ArrayList stored in the first index of the outer ArrayList, cat ID numbers in the second, and lizard ID numbers in the third.This will happen in a random order so I want the outer ArrayList to have it's size already initialized so I can send an ID number to it's correct inner list when I come across it . This is what I did:
ArrayList<ArrayList<Integer>> outer = new ArrayList<ArrayList<Integer>>(capacity);
ArrayList<Integer> inner = new ArrayList<Integer>();
for (int i = 0; i < capacity; i++) {
outer.add(null);
}
Would initializing those indices to null increase the size to whatever number is stored in capacity and allow me to later add a dog to inner by doing outer.get(3).add(10) and then outer.get(0).add(22)?
I also thought about doing this:
ArrayList<ArrayList<Integer>> outer = new ArrayList<ArrayList<Integer>>(capacity);
ArrayList<Integer> inner = new ArrayList<Integer>();
for (int i = 0; i < capacity; i++) {
outer.add(inner);
}
But don't know if adding inner would actually initialize all indices in outer to Integer ArrayLists or if they would be referencing the "inner" variable itself or something like that.
ArrayList has size (the number of elements) and capacity (the number of elements it can hold before it needs to automatically expand) which can be used for optimization, for now you can safely ignore capacity and just add and remove elements based on your needs.
Create the outer array with:
ArrayList<ArrayList<Integer>> outer = new ArrayList<>();
And then add all the inner arrays you need:
for (int i = 0; i < capacity; i++) {
outer.add(new ArrayList<Integer>());
}
Related
I have an ArrayList of ArrayLists of Integers. [ArrayList > list]. How do I set value foe an index of any inner ArrayList? I do not want to build an ArrayList of Integers and add them to the List of List using add function, but I want to set values to it, as I already have the List of List.
I'm assuming you have something like:
List<List<Integer>> list = new ArrayList<>(outerSize);
You've also said:
I do not want to build an ArrayList of Integers and add them to the List of List using add function, but I want to set values to it, as I already have the List of List.
If that's true, it means you've already done this or similar:
for (int i = 0; i < outerSize; ++i) {
List<Integer> inner = new ArrayList<>(innerSize);
for (int j = 0; i < innerSize; ++i) {
inner.add(defaultValue);
}
list.add(inner);
}
So given all of that, it's just get (to get the inner list from the outer list) and set (to set a value on it):
list.get(outerIndex).set(innerIndex, value);
I have a 2-dimensional ArrayList Object
private ArrayList<ArrayList<Short>> VOL_2D = new ArrayList<ArrayList<Short>>();
Now I want to call .ensureCapacity() on both the outer list and all the inner lists (The number of inner lists is know, but they are not initialized yet). For the outer list it is easy, I just define how many inner lists I want to fit inside.
Is there a nice way of calling this method on the inner lists? Or do I have to call it every time I initialize a new inner list?
There's no thing like "2-dimensional ArrayList Object". You have an ArrayList which stores ArrayList objects inside it. All of objects stored in the outer list may have different sizes, some of them may be null or subclasses of ArrayList. So you have to explicitly add enough ArrayList objects into the outer array list:
int n = // size of the outer list
int m = // size of the inner lists
private ArrayList<ArrayList<Short>> VOL_2D = new ArrayList<ArrayList<Short>>(n);
for(int i=0; i<n; i++)
VOL_2D.add(new ArrayList<>(m));
Please note that ensureCapacity does not actually add any elements to the list. It just resizes the internal array to fit the specified number of elements, so subsequent resizes will not be necessary. Creating an empty ArrayList and calling ensureCapacity right after this is meaningless: better to use the ArrayList(minCapacity) constructor which will do the same in more effective way. Anyways ensureCapacity is useful just to improve the performance. If you actually want to have elements inside these lists, you may use:
for(int i=0; i<n; i++) {
ArrayList<Short> inner = new ArrayList<>(m);
for(int j=0; j<m; j++)
inner.add(null); // or some other initial value
VOL_2D.add(inner);
}
Finally if you want to have two-dimensional ArrayList of fixed size, why not just create array like this?
private short[][] VOL_2D = new short[n][m];
It would be much more performant.
It seems that you don't understand what this construct really means. You see, those "inner" lists have no idea that they might be collected in some outer list. So there is no way to (easily) achieve what you are looking for.
One possibility though: you could extend ArrayList; and in your own class, you can overwrite all methods that would "add" an ArrayList ... you can do whatever you want; for example set the desired capcity.
You don't need to call ensureCapacity
It's just a method used for optimisation to avoid unnecessary reallocation of the underlying array data structure.
From the docs
An application can increase the capacity of an ArrayList instance
before adding a large number of elements using the ensureCapacity
operation. This may reduce the amount of incremental reallocation.
If the outer ArrayList size is known, and fixed then I would recommend you to use array instead of ArrayList, like below.
int size = 10;
ArrayList<Short>[] VOL_2D = new ArrayList<Short>[size];
Why do you need to call ensureCapacity(int minCapacity)? Could you elaborate your usecase? Because when you create instance you can specify the size of ArrayList. like below
VOL_2D[0] = new ArrayList<Short>(30);
This will invoke below constructor, and create an array size of 30
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
To answer your question, there is no single in-built method which will iterate all elements in list and call ensureCapacity.
You need to write code for this, like below
for(ArrayList<Short> vol : VOL_2D){
vol.ensureCapacity(30);
}
Remember this, before call ensureCapacity method, you need to initialize your ArrayList object (in your case all inner ArrayList object), otherwise you will end up with NullPointerException.
I am only in my 8th week of Java, so I am quite new.
I have a class that has an ArrayList object, list. I have another class called TransactionCalc. I would like for TransactionCalc to have its own ArrayList object, called arr3. I need to have be exactly as large as list. I know how to declare an ArrayList that is a size other than 10, but how do you do this if you do not yet know the exact size? Is it possible?
public class TransactionCalc extends CalculateAbstract{
private int count = 0;
private ArrayList <ItemAttribute> arr3 = new ArrayList <ItemAttribute> (1);
//the 1 needs to be list.size() ??
I am assuming that in the other class I will need to do public static final int = list.size(), but is it possible to get that constant over to the TransactionCalc class so that it can be in the declaration?
I forgot to add this... since the functionality of arrayList is not really needed, I could also do list.toArray(arr3) but that still wouldn't allow for it to be an object of the TransactionCalc class. Is it possible to do that? I'd like to avoid sending the same arr3 over and over again to multiple methods in the same class.
Also, how would I put this as a constructor?
EDIT with help from amaleemur____________
I have updated my code to have:
public class FindItemInfo implements InterfacePrint{
ArrayList <ItemAttribute> list = new ArrayList<ItemAttribute>();
//load arraylist and do something with it
//sort arraylist
public void printPriority(){
TransactionCalc finish = new TransactionCalc();
for (int i = 0; i < list.size(); i++){
for (int x = 0; x < list.size(); x++){
if(arr2.get(i) == list.get(x).getPriority()){
finish.cashOut(list.get(x), bankAccount, list.size());
} //send sorted arr2 to TransactionCalc class
}
}
public static int getListSize(){
return list.size();
}
}
public class TransactionCalc {//extends CalculateAbstract{
private int count = 0;
//private ArrayList <ItemAttribute> arr3 = new ArrayList <ItemAttribute> (FindItemInfo.getListSize());
private ItemAttribute[] arr3 = new ItemAttribute[FindItemInfo.getListSize()];
public void cashOut (ItemAttribute item, double bankAccount, int size) {
//ItemAttribute[] arr3 = new ItemAttribute[size];
double runningTotal = 0;
if((runningTotal + (item.getQuantity()*item.getPrice()))<= bankAccount){
runningTotal += item.getQuantity()*item.getPrice();
bankAccount -= runningTotal;
System.out.format("You will spend $%.2f on " + item.getQuantity() + " of "+ item.getDescription(), runningTotal);
System.out.format(" and have $%.2f left to spend\n", bankAccount);
}
else{
arr3[count] = item;
count++;
}
}
I am making arr3 an object of the TransactionCalc class because it is used for a few methods. The purpose of the array/arraylist is to collect the items that are not being printed. I can use either an array or an arraylist. I initially went with an array but then didn't know the size.
I am now getting static and non-static errors. When I go to try and fix this, it causes more problems.
The neat thing about using an ArrayList is that you don't have to declare a size.
so this is sufficient and you can add items to the array list.
private ArrayList <ItemAttribute> arr3 = new ArrayList <ItemAttribute>();
in order to get the size of list, I would suggest doing this:
In your class that contains the ArrayList list, create a method
public int getListSize(){
return list.size();
}
and now you can safely access the size of list. Does this help?
so now you'd do this:
private ArrayList <ItemAttribute> arr3 =
new ArrayList <ItemAttribute>(otherClass.getListSize());
where otherClass is a placeholder for the name of your other class with the ArrayList list.
ArrayList is a mutable collection type. This means (in this case) that instances of ArrayList may host arbitrary amounts of elements and in particular, the contained elements of a given instance of ArrayList may change at runtime. So you do not have to declare the amount of elements. In typical cases, you will most likely want to use the default c'tor (=not specify the initial amount of elements). Specifying the initial amount if elements may be a good idea (performance-wise), if you know that there will be a large number of objects inserted at run-time. In such cases, initialising an instance of ArrayList may safe some memory allocations an memcopy operations.
I am looking at the code for Permutations problem on leetcode. For example,
[1,2,3] have the following permutations:
[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1].
And I found there is one sentence
ArrayList<Integer> temp = new ArrayList<Integer>(l);
I have no idea why here needs to assign the "l" to "temp". And I tried current.add(l) direclty but gave me the wrong answer. Can you help me with this?
public class Solution {
public ArrayList<ArrayList<Integer>> permute(int[] num) {
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
//start from an empty list
result.add(new ArrayList<Integer>());
for (int i = 0; i < num.length; i++) {
//list of list in current iteration of the array num
ArrayList<ArrayList<Integer>> current = new ArrayList<ArrayList<Integer>>();
for (ArrayList<Integer> l : result) {
// # of locations to insert is largest index + 1
for (int j = 0; j < l.size()+1; j++) {
// + add num[i] to different locations
l.add(j, num[i]);
ArrayList<Integer> temp = new ArrayList<Integer>(l);
current.add(temp);
//System.out.println(temp);
// - remove num[i] add
l.remove(j);
}
}
result = new ArrayList<ArrayList<Integer>>(current);
}
return result;
}
}
I have no idea why here needs to assign the "l" to "temp"
He's not - that would just be:
ArrayList<Integer> temp = l;
Instead, the code creates a copy of the content of the list l refers to, in a new ArrayList. That means that future changes to the list that l refers to (such as the call to l.remove(j) immediately afterwards) don't affect the new list.
As a simple stand-alone example of that, consider:
List<String> original = new ArrayList<>();
original.add("foo");
List<String> copy = new ArrayList<>(original);
System.out.println(copy.size()); // 1
original.add("bar");
System.out.println(copy.size()); // Still 1
Admittedly the code is written in a very odd manner - until the final statement, result only ever has a single element, so iterating over it is pretty pointless - but I believe that explains the single statement you were asking about.
If you did
current.add(l);
you would be adding the same reference to the ArrayList l to current. So, if you made some changes in one of those lists, both would be modified. In order to avoid that issue, in the line
ArrayList<Integer> temp = new ArrayList<Integer>(l);
you are creating a different ArrayList but with the same content. So, they will be different objects (different references).
I know that for arrays you can add an element in a two dimensional array this way:
array[0][1] = 17; //just an example
How can I do the same thing with ArrayList?
myList.get(0).set(1, 17);
maybe?
This assumes a nested ArrayList, i.e.
ArrayList<ArrayList<Integer>> myList;
And to pick on your choice of words: This assigns a value to a specific place in the inner list, it doesn't add one. But so does your code example, as arrays are of a fixed size, so you have to create them in the right size and then assign values to the individual element slots.
If you actually want to add an element, then of course it's .add(17), but that's not what your code did, so I went with the code above.
outerList.get(0).set(1, 17);
with outerList being a List<List<Integer>>.
Remember that 2-dimensional arrays don't exist. They're in fact arrays or arrays.
ArrayList<ArrayList<String>> data = new ArrayList<ArrayList<String>>();
data.add(new ArrayList<String>());
data.get(0).add("String");
ArrayList<ArrayList<String>> contains elements of type ArrayList<String>
Each element must be initialised
These elements contain elements of type String
To get back the String "String" in the 3-line example, you would use
String getValue = data.get(0).get(0);
the way i found best and convinient for me was to declare ur 2d arrayList and then also a nornal mono-dimension array.
ArrayList<ArrayList<String>> 2darraylist = new ArrayList<>();
ArrayList<String> 1darraylist=new ArrayList<>();
then fill the '1D'array list and later add the 1D to the 2D array list.
1darraylist.add("string data");
2darraylist.add(idarraylist);
this will work as long as your problem is simply to add to elements to the list. if u want to add them to specific positions in the list, the the .get().set(); is what u wanna stick to.
ArrayList<ArrayList<Integer>> FLCP = new ArrayList<ArrayList<Integer>>();
FLCP.add(new ArrayList<Integer>());
FLCP.get(0).add(new Integer(0));
Each element must be instantiated. Here the outer ArrayList has ArrayList element, and first you need to add an element to reference it using get method.
Some additional notes; after reading other answers and comments:
1> Each element must be instantiated; initialization is different from instantiation (refer to flexJavaMysql's answer)
2> In Java, 2-dimensional arrays do exist; C# doesn't have 2D arrays (refer to JB Nizet's answer)
String[] myList = {"a","b","c","d"};
ArrayList<ArrayList<String>> data = new ArrayList<ArrayList<String>>();
data.add(new ArrayList<String>());
int outerIndex =0;
int innerIndex =0;
for (int i =0; i<list.length; i++) {
data.get(outerIndex).add(innerIndex, list[i]);
innerIndex++;
}
System.out.println(data);
Simple for loop to add data to a multidimensional Array.
For every outer index you need to add
data.add(new ArrayList<String>());
then increment the outer index, and reset the inner index.
That would look something like this.
public static String[] myList = {"a", "b","-","c","d","-","e","f","-"};
public static ArrayList<ArrayList<String>> splitList(String[] list) {
ArrayList<ArrayList<String>> data = new ArrayList<ArrayList<String>>();
data.add(new ArrayList<String>());
int outerIndex =0;
int innerIndex =0;
for (int i=0; i<list.length; i++) {
System.out.println("will add: " + list[i]);
if(!list[i].contains("-")) {
System.out.println("outerIndex: " + outerIndex +" innerIndex: "+ innerIndex);
data.get(outerIndex).add(innerIndex, list[i]);
innerIndex++;
} else {
outerIndex++; // will move to next outerIndex
innerIndex = 0; // reset or you will be out of bounds
if (i != list.length-1) {
data.add(new ArrayList<String>()); // create an new outer index until your list is empty
}
}
}
return data;
}
public static void main(String[] args) {
System.out.println(splitList(myList));
}