Difference between 2d string array and Array list of string - java

Im using
ArrayList<ArrayList<String>> Stringdata = new ArrayList<ArrayList<String>>();
to make a 2d array of string
how is it different from using
String Stringdata[][] = new String[10][10];

An ArrayList is a class that implements the interface List.
An array as per declared by:String[] variable is a finite-length data-structure in Java.
The main difference in using a 2D ArrayList instead of a normal array is that the length of an ArrayList is not limited. You may add as many elements to an ArrayList as your RAM allows.
On the other hand, String[][] stringData = new String[10][10]; would limit this matrix to 100 elements (10 rows with 10 elements each). If trying to add an element to index 10 (notice the index only goes from 0 to 9) of a 10x10 matrix, the compiler would throw an error.
In general, if you already know how many spaces you will need in your matrix it is recommended that you use an array. Else, ArrayLists are really good.

Related

How are 2d arrays structured?

When I was taught 2d arrays, I was taught that they are arrays of arrays, similar to an array of ArrayLists. But I was thinking about it and it is actually really confusing:
ArrayList[] arrOfList = new ArrayList[5];
arrOfList[0] = new ArrayList<Integer>();
arrOfList[0].add(1);
arrOfList[0].add(2);
arrOfList[0].add(3);
//arrOfList[0] is the first list, with 3 elements
//arrOfList is an array of 5 lists; arrOfList.length = 5
int[][] arrOfArr = new int[3][5];
//arrOfArr[0] is NOT an array with 3 elements
//arrOfArr is NOT an array of 5 arrays; arrOfArr.length = 3
I think what I'm getting at is more clear if I bold the parts that I think would correlate (but don't):
ArrayList[] arrOfList = new ArrayList[5];
int[][] arrOfArr = new int[3][5];
What is a more intuitive way of thinking about declaring 2d arrays, since relating it to an arbitrary type is not right? (as illustrated above)
This may help you visualize it more.
When using square brackets [], first pair is always row, second pair is columns.
In both scenarios, the first dimension (row) saves the memory address of the corresponding Array / ArrayLists.
The second dimension (column) saves the corresponding value stored in that particular row of Array/ArrayList.
What you are taught is correct. An array of arrays is similar to an array of arraylists, with the exception that arraylists have variable length. The implication is that with an array of arraylists, the width (no. of columns) isn't static.
ArrayList[] arrOfList = new ArrayList[5]
This is saying, create an Array of length 5 (5 rows), with the data type being ArrayList (of variable length, thus can be any number of columns).
int[][] arrOfArr = new int[3][5]
This is saying, create an Array of length 3 (3 rows), with the data type being Array with length 5 (5 columns).
The fact that an ArrayList has variable length is likely causing the confusion, but I still stand by the same answer: first pair of [] = row; second pair of [] = column.
int[][] arrOfArr = new int[3][5]
That creates an empty grid of array cells with 3 rows and 5 columns. i.e.
[][][][][]
[][][][][]
[][][][][]
Then to fill those columns you just do arrOfArr[0][2] = 4 which goes down to row 0 and across to column 2. i.e.
[][][4][][]
[][][][][]
[][][][][]
Alternatively, see it as a set of 3 lots of 5 cell arrays
[][][4][][], [][][][][], [][][][][]
int[][] arrOfArr = new int[3][5];
//arrOfArr[3] is the number of rows
//arrOfArr[5] is the number of colums

How can I make an array of my arrays in Java? (WITHOUT ArrayLists)

I have a few multidimensional arrays of type char[][].
Eg..
char[][] ARRAY_1 = {
{'.','#'},
{'$','#'}
}
char[][] ARRAY_2 = {
{'.','#'},
{'$','#'}
}
And I want to make an array or list of some sort such as
ARRAY = {ARRAY_1,ARRAY_2,...}
so I'll be able to put in ARRAY[1] (or something similar) and have it return the entire char[][] ARRAY_1
I am very new to programming with Java so I'm not sure what the best way to do this is.
Edit: I've just found out I'm not allowed to use ArrayLists.
Direct answer: use ArrayList<char[][]> or char[][][].
Basically, you create an ArrayList that holds your 2 dimensional arrays or a 3 dimensional array of chars.
List<char[][]> array = new ArrayList<>();
or
char[][][] array = char[length][][];
To add the arrays, you just use the following:
array.add(arrayOne); //for an ArrayList
array.add(arrayTwo);
or
array[0] = arrayOne; //for an array
array[1] = arrayTwo;
To get the arrays, you just use the following (where the number is the index):
array.get(0); //for an ArrayList
array.get(1);
or
array[0]; //for an array
array[1];
Check out the ArrayList javadoc for more information.
(edit: variable changed to match naming conventions)
So ... if you are not allowed to use lists ... this is one way to make an array of existing arrays.
char[][][] ARRAY = new char[][][]{ARRAY_1, ARRAY_2};
Insight #1: an N-dimension array in Java is an array of N-1 dimension arrays (assuming N > 1).
Insight #2: arrays are indexed from zero.
How would I call the arrays individually again later on?
You still have the names of the original arrays ... in your example.
Base on insight #1":
char[][] ARRAY_1_AGAIN = ARRAYS[0];
System.out.println(ARRAY_1 == ARRAY_1_AGAIN); // prints true
Since ARRAY_1 is the first subarray of ARRAY (as per the previous example), we need to use ARRAYS[0] (not ARRAYS[0]) to access it.
Try this:
List<char[][]> list = new ArrayList<>();
list.add(ARRAY_1);
list.add(ARRAY_2);
Or
char[][][] ARRAY = new char[length][][];
ARRAY[0] = ARRAY_1;
ARRAY[1] = ARRAY_2;
Or
char[][][] ARRAY = new char[][][]{ARRAY_1, ARRAY_2};
Further reading:
ArrayLists in Java
You are using a Jagged Array...
Also try this
char[][] array = new char[5][];
array[0] = array1;
array[1] = array2;
Regards

Does a 1D array of N elements need the same amount of memory as 2D[m][n], m*n=N

Here's the question about memory allocation in Java.
Suppose I have an array of ints A[100] and another array of ints B[10][10]. Do they need the same amount of memory in Java or is it different? If the latter, what's the difference and how does it grow with N?
I'm talking here only about Ns that are power of 2 of a positive number, so we're talking here about square 2D arrays and their possible 1D representation.
Definitively, no.
In C/C++ a 2D-array allocates all memory for the 2D-array in "one chunk".
In Java, a 2D-array is an "array of arrays". One-dimensional arrays are allocated in one chunk, but the one-dimensional arrays may be scattered. Furthermore, the "outer" array (2nd dimension) needs heap memory as well, storing the references to the 1D-arrays.
So if one allocates a 2D-array of dimensions m (outer) and n (inner), Java will create one array of m elements and m arrays ofn elements each. The outer array just stores the references to the m inner arrays.
This page gives a nice explanation and visualization of multidimensional arrays in Java.
This is empirical confirmation of #Turing85's answer, and measurement of the overhead. This program alternately allocates and frees a single array of a million elements or an int[1000][1000], reporting the amount of memory in use at each step. It quickly settles down to:
Neither: 291696
1D: 4291696
Neither: 291696
2D: 4311696
showing an extra 20,000 bytes of memory in use for the 2D case.
Here is the program:
public class Test {
public static void main(String[] args) {
int M=1000;
for(int i=0; i<10; i++){
System.out.println("Neither: "+inUseMem());
int[] oneArray = new int[M*M];
System.out.println("1D: "+inUseMem());
oneArray = null;
System.out.println("Neither: "+inUseMem());
int[][] twoArray = new int[M][M];
System.out.println("2D: "+inUseMem());
twoArray = null;
}
}
private static long inUseMem() {
System.gc();
return Runtime.getRuntime().totalMemory()
- Runtime.getRuntime().freeMemory();
}
}
Running this program on the system of interest using the actual array sizes should show the cost of using the 2D array. If the arrays really are around 10,000 elements total, it is probably best to go with whatever makes the code more readable.
When an object is creating by using “new”, memory is allocated on the heap and a reference is returned. This is also true for arrays, since arrays are objects.
Single-dimension Array
int arr[] = new int3;
The int[] arr is just the reference to the array of 3 integer. If you create an array with 10 integer, it is the same – an array is allocated and a reference is returned.
Two-dimensional Array
Actually, we can only have one dimensional arrays in Java. 2D arrays are basically just one dimensional arrays of one dimensional arrays.
int[ ][ ] arr = new int[3][ ];
arr[0] = new int[3];
arr[1] = new int[5];
arr[2] = new int[4];
Multi-dimensional arrays use the name rules.
As you can observe that while managing a 2D array extra 1D array is needed thus in terms of memory the size differ but from users view both have same size.
Images were taken form this site.

Multi-dimensional arrays in Java

I am preparing for OCAJP exam, I got a problem with the multi-dimensional arrays in java. After go through a video tutorial on YouTube, I think I got an idea about how it works. It says the following statement creates two double dimensional arrays and one array to hold both arrays. Hence it is a three dimensional array.
int arr[][][] = new int[2][4][3];
So I want to get confirmed, that if I want a five dimensional array, this statement would do it.
int arr[][][] = new int[4][4][3];
Try to visualise it geometrically.
A 1-dimensional array is just a list: new int[2]
A 2-dimensional array is a rectangular grid (or a list of lists): new int[2][3]
A 3-dimensional array is a cuboid (or a list of rectangles, or a list
of lists of lists): new int[2][3][4]
After this it gets harder, but :
a 4D array is a list of cuboids (a list
of lists of lists of lists) new int[2][3][4][5]
a 5D array is a grid of cuboids (a list
of lists of lists of lists of lists): new int[2][3][4][5][6]
int arr[][][] = new int[4][4][3];
Is still a 3 dimensional array.
A 5 dimensional array looks like
int arr[][][][][] = new int[4][4][3][4][3];
int arr[][][][][] = new int[4][4][3][X][X];
x can be any number. this is a 5 dimentional array.
Imagine a cube.
int arr[][][] = new int[2][4][3];
Here you have 2 slices of an array of 4x3.
int arr[][][] = new int[4][4][3];
With this, you have 4 slices of an array of 4x3.
So, it stills a three dimensional array.
However, you can save 4 different two dimensional arrays there.
every time you add a new dimension the number of elements grow exponentially. int[4][4][3] means a 3-dimensions array with 4*4*3=48 elements. to create a 5-dimension array add 2 more square-brackets int[2][2][2][2][2] which is an array with 2^5 elements(2*2*2*2*2)

Element of an array as a reference to another array?

I am trying to have a 2D Array that is 16 rows by 11 columns where row 0, column 3 is a reference to another array that is a single dimension array. How do i go about doing this? I already have both arrays where the single dimension array is a char array(although i could make it a string array if i wanted) and the 2D array is a string array. The rest of the 2D Array is filled with plain strings for each elements with the exception of row 0, column 3 which i want it to be the single dimension array.
Object[] arrayToReference = ...;
Object[][] arrayWithReference = new Object[] { ..., arrayToReference, ...};
This should work; just reference the array and it should change as the original changes
Here's an example code snippet:
Object[] array = new Object[] { "Test!" };
Object[][] arrayArray = new Object[][] { array };
System.out.println("Before: " + arrayArray[0][0]);
array[0] = "Test2!";
System.out.println("After: " + arrayArray[0][0]);
which has the following output:
Before: Test!
After: Test2!
That just sounds like your approach to the problem is wrong. Maybe you should rethink your data structure. Normally, an array is typed. You can't really decide to insert a different type in one cell.
If you really can't change the data structure, try inserting a single dimension array of strings in each cell with only 1 entry in them, which is the string that goes there normally, except for row 0, column 3, which already is an array.
I'm thinking a bit of an overkill solution, but should work for this with some refining. If it is possible for you.
Can you make two classes that implement the same interface? First one will be the type of the 2D array, and the other one would be class with the 1D array.
Since they implement a common interface, you can make a 2D array with that interface. That kind of 2D array can accept any kind of the two objects on any place in it.

Categories