I am confused on copying 2D arrays - java

I was reading this post on Stack overflow: copy a 2d array in java and I am a little confused on how the clone method works here...
public int[][] CopyMap(int[][] Map)
{
int [][] copy = new int[Map.length][];
for(int i = 0; i < Map.length; i++)
copy[i] = Map[i].clone();
return copy;
}
I know how to copy using enhanced for loops but I would like to fully understand this way.
1) Why do we put the Map.length in the first set of square brackets but not Map[0].length in the second set of square brackets for int[][] copy = new int[Map.length][];? Don't we have to initialize the length of the columns as well? I'm guessing that we can't clone a 2D array but we can clone a row or column at a time.
2) By cloning the columns one column at a time and putting it into our 2D array it sets the length of the columns for us?
3) Could we reverse this code by doing this
public int[][] CopyMap(int[][] Map)
{
int [][] copy = new int[][Map[0].length];
for(int i = 0; i < Map[0].length; i++)
copy[i] = Map[i].clone();
return copy;
}
4) Also copy[i] ? This is a 2D array, so shouldn't it be copy[i][] ? Or something like that.

In Java a 2D array is essentially an array of arrays (possibly with different lengths). It is important to remember this. For example, this is OK:
int[][] ar = new int[2][];
ar[0] = new int[8]; // ar[0][0..7]
ar[1] = new int[4]; // ar[1][0..3]
The syntax new int[8][10] can be used as a convenience to create 8 separate arrays of 10 elements each.
If you are familiar with C: an int[][] in Java is more similar to an int** in C.
Note: Map is a terrible name for a variable in Java; variable names generally start with lowercase letters and there is also a very common base container interface of the same name.
1) Why do we put the Map.length in the first set of square brackets but not Map[0].length in the second set of square brackets for int [][] copy = new int[Map.length][]; ?
Because we are starting with an array of Map.length int[]'s, and then cloning those int[]s one at a time.
Don't we have to initialize the length of the columns as well?
No, because when we go through each int[] in Map, we just use clone() to copy it: copy[i] = Map[i].clone().
By cloning the columns one column at a time and putting it into our 2D array it sets the length of the columns for us?
A "column" is just a concept you made up that is only relevant to tabular data (column-major tabular data in your specific context). Anyways, "setting the length" isn't exactly accurate because it implied that something whose length is being set existed in the first place; but when you do int x[][] = new x[5][], x[0] is null until you assign it to something. By cloning the int[]s one at a time, we're just... cloning them one at a time. So, yes, each clone will be the same size as the original.
3) Could we reverse this code by doing this
public int[][] CopyMap(int[][] Map)
{
int [][] copy = new int[][Map[0].length];
for(int i = 0; i < Map[0].length; i++)
copy[i] = Map[i].clone();
return copy;
}
No; and hopefully the reason why is clear now that you know that an int[][] is an array of arrays. The expression new int[][size] doesn't make much sense; it says that we want each int[] in the array to have a given size, but it doesn't say how many int[]s are in the array. It's wrong for the same reason that int[] x = new int[] is wrong.
4) Also copy[i] ? This is a 2D array, so shouldn't it be copy[i][] ? Or something like that.
No, it should be copy[i]. I'll leave figuring out the reasons as an exercise.

Related

Get size of second dimension while first dimension is empty [duplicate]

Well, that might be a strange question, and maybe just because I'm not familiar enough with Java.
So, I declared a 2D int array:
int[][] arr = new int[0][10]
Now, as you can see, the second dimension's length is 10, while the first dimension's length is 0. I'm not sure how Java treats these kind of arrays, but the compiler doesn't produce any errors, which means it's a legit declaration.
Well, I passed the array to some function, and I want to retrieve from within the function, the length of the second dimension.
Of course something like:
arr[0].length
won't work. is there another way to do this?
The objects created by new int[0][10] and new int[0][20] are equivalent. There is no logical "second dimension" here. Effectively you're running something like this:
int[][] createArray(int d1, int d2) {
int[][] ret = new int[d1][];
for (int i = 0; i < d1; i++) {
ret[i] = new int[d2];
}
return ret;
}
Now if you translate that into your scenario, you'll end up with code which never reads d2.
If you want to represent a general-purpose rectangular array (instead of an array of arrays) you might want to consider creating your own type for it.
Arrays in Java, and most every other programming language, are zero-based. Consider this 2D array:
int[][] arr = new int[1][10];
This means that there is one row and ten columns in it.
Now, consider this array:
int[][] arr = new int[0][10];
This means that there are zero rows and (an irrelevant amount of columns) in it.
If you try to index into the second array, you'll find that you can't - an array of length zero has no starting point.
The compiler sees it as valid because you declared dimensions with it, but you won't be able to actually use it in any meaningful way in Java.
There is no such thing as the length of the second dimension. Consider:
int[][] arr = new int[10][10];
arr[5] = new int[42];
What is the length of the second dimension? 10 or 42?
No. It doesnt work this way. arr is an array with ten elements, each of which must be a reference of an int array (or null). That's all there is to say.

How do I create a 2d array made of 2d int arrays in java?

I want to create a 2d array that is made of smaller 2d integer arrays, to overall make a matrix graph. Instead of storing integers in the bigger array I would store 2d integer arrays.
Edit: I think drew the array I want incorrectly. What I meant was I want to create a grid (matrix - 2d array) where inside each cell of the grid instead of there being stored a int, boolean, etc. I would like to store a 2d int array in each cell of the grid.
I was thinking something like int[int[][]][int[][]]. But realized that wouldn't work since the outer array isn't an integer array, it is just a general array made of integer arrays.
I found codes in other questions here that have a 2d array of objects (ex. room[][]) but I don't think that would be necessary since the array I'm trying to make is made of int[][] arrays, correct?
So how could I got about this?
Thanks in advance!
In Java multi-dimentional arrays are implemented as array of arrays approach and not matrix form. To implement the data structure provided in the request array has to be implemented as below,
Data Structure :
{{{0,1}, {{0,1},
{2,3}}, {2,3}},
{{0,1}, {{0,1},
{2,3}}, {2,3}}}
Array Declaration and assignment :
public class MyClass {
public static void main(String args[]) {
int[][][][] q =new int[2][2][2][2];
q[0][0][0][0] = 0;
q[0][0][0][1] = 1;
q[0][0][1][0] = 0;
q[0][0][1][1] = 1;
q[0][1][0][0] = 2;
q[0][1][0][1] = 3;
q[0][1][1][0] = 2;
q[0][1][1][1] = 3;
q[1][0][0][0] = 0;
q[1][0][0][1] = 1;
q[1][0][1][0] = 0;
q[1][0][1][1] = 1;
q[1][1][0][0] = 2;
q[1][1][0][1] = 3;
q[1][1][1][0] = 2;
q[1][1][1][1] = 3;
}
}
It seems 4D array, use int[][][][] to store data.
4D array means 2D array of 2D array
Example: int[][][][] arr = new int[10][20][10][10]
It creates a 2D array of 10X20 size where for each cell there is 2D array of 10X10.

Can we add elements in an array dynamically and also print it when the size is unknown, in java

Adding elements to an array in java ,given the size, is easy to code but doing it dynamically poses a problem .
Ex:
Int a[]= new Int[5];
a[0]=0;
a[1]=2;
a[2]=2;
a[3]=3;
a[4]=4;
Here(in the above example) we know the size, so I can assign the values. What If don't know how many values I have to add, in some cases it could be 5 and some other it might be 100.
So for such a situation I would need an array which will take input dynamically(as many as I input) or on spot.
My question is how to make an array dynamic in Java?
It could be done using List, but is there a way using array?
Please help me out
You can't allocate dynamically an array, but you can always create a new one when this one is full. This is a method to call when the array is full. it will return a new array with more elements and will get the elements from the old array:
public int[] createNewArray(int[] oldArray){
int[] newArray = new int[oldArray.length * 2];
for(int i = 0; i < oldArray.length; i++) {
newArray[i] = oldArray[i];
}
return newArray;
}

Choose second dimension of array, but use whole first dimension

Let's say I have a two dimensional array defined as:
boolean[][] col = new boolean[8][3];
Now how would I go about accessing all 8 values from the first dimension from any of the 3 locations on the second dimension? For example, col[0] would do what I want, but reversed.
For further clarification, I need to know how to access one of the 3 arrays with 8 values in it, rather than one of the 8 arrays with 3 values in them.
While this isn't exactly what I was looking for, I have found a computationally slow and large solution:
boolean[] getA(int k) {
boolean[] buf = new boolean[8];
for(int i = 0; i < 8; i++) {
buf[i] = col[i][k];
}
return buf;
}

How to add / remove different class instances from arrayList stored inside a mulitidimentional array in java

My overall thought process may be off here so if there is a more logical solution to this feel free to suggest. The problem is this, I have a 2 dimensional array that I am treating as an x,y grid system. I would like to be able to store multiple class instances inside a single array index. my thought was to instead store an array list inside each array index as a sort of container for the objects. The problem is that I'm not sure how to address the list that is inside a given index at array[i][j].
One solution I considered is to create a templist and set tempList = array[i][j] edit tempList set array[i][j] = tempList. Sort of a switcheroo. Is there a better way to do this?
You can edit the lists directly, without any need for temporary variables.
To set a list:
array[0][0] = new ArrayList<>();
So you can fill the entire array with something along these lines:
int width = 100;
int height = 100;
List[][] array = new List[width][height];
for(int x = 0; x < width; x++){
for(int y = 0; y < height; y++){
array[x][y] = new ArrayList<Object>();
}
}
The array will have all it's elements set to null by default, so you will have to create a list at every index.
The above code will create an ArrayList at every position in the array, which you can then use just like any other list:
array[0][0].add(element); //Adds the element to the list at [0,0]
Object obj = array[0][0].get(0); //Gets the element we just added

Categories