Java Copying Data from Array Rather than Reference - java

In the following code, I am trying to duplicate the 2d array 'cur,' swapping two values in the array, and eventually add it to an arraylist I will be using later in the program. My problem is, every time I switch these values in the array 'temp' (has the cloned values of 'cur') it also switches the values in the array 'cur.' I'm confused because I have tried clone(), Arrays.copyof, even made a new constructor for the PuzzleNode class that takes the values from cur, yet every time 'cur' doesn't reset to its original value when the iteration of the loop finishes. Any help is much appreciated.
Here's the code:
//generate the puzzles and swap the tiles
for (int i = 0; i < possibleSwaps.size(); i++) {
//stores the 2d array of Nodes
PuzzleNode temp = new PuzzleNode();
//instantiate the 2d array and populate it with values of cur
temp.puzzle = new Node[cur.puzzle.length][cur.puzzle[0].length];
for (int j = 0; j < cur.puzzle.length; j++) {
temp.puzzle[j] = cur.puzzle[j].clone();
}
for (int j = 0; j < cur.puzzle.length; j++) {
for (int k = 0; k < cur.puzzle[0].length; k++) {
if (temp.puzzle[j][k].value == possibleSwaps.get(i).value) {
//switch the values, values should always be distinct
int prev = temp.puzzle[zeroNode.x][zeroNode.y].value;
temp.puzzle[zeroNode.x][zeroNode.y].value = possibleSwaps.get(i).value;
temp.puzzle[possibleSwaps.get(i).x][possibleSwaps.get(i).y].value = prev;
}
}
}
//prints out the 2d array that should be the same everytime. But isn't
printPuzzle(cur.puzzle);
}
Example of Print Out:
(Original 2d array I want to always have)
1 2 3
4 6 8
7 [] 5
(Switched the [] and the 6, I NEED the [] to remain where it originally was in the previous iteration, so it can be swapped with the 5 and 7 in the next iterations)
1 2 3
4 [] 8
7 6 5
(Stays where it was swapped in the previous iteration)
1 2 3
4 [] 8
7 5 6
1 2 3
4 [] 8
5 7 6

Related

Filling in 2D Array into 3D Array in Java

I want to write a Method where I get a 3x6 workingArray (but might also be 3x5, 3x4...) and a 3x3 (maybe also different size) filteringArray and make an 3D Array (holdArrays) where I put in the first Array to make a square (in this case 3x3), then move one position and put in another 3x3, till the last column of workingArray has been covered.
Somehow I get an nullPointerException in '//affected line' and I can't see why. So I wonder if I do this the right way and I haven't found resources for how to put 2D Arrays into 3D Array.
Example:
1 2 3 4 1 2 3 2 3 4
5 6 7 8 to 5 6 7 and 6 7 8
9 1 2 3 9 1 2 1 2 3
private static void filtering(double[][] workingArray, double[][] filteringArray) {
// creating amount of holdArrays to work with filterArray
double[][][] holdArrays = new double[workingArray.length - filteringArray.length + 1][filteringArray.length][];
// filling in the parted workingArray into holdArrays
for (int i = 0; i < holdArrays.length; i++) {
for (int j = 0; j < filteringArray.length; j++) {
for (int k = 0; k < filteringArray[j].length; k++) {
holdArrays[i][j][k] = workingArray[j][k]; //affected line
}
}
}
}
The size of the last dimension is not specified. And since the line
holdArrays[i][j][k] tries to access the kth element which is not there, it throws a Null Pointer Exception.
double[][][] holdArrays = new double[workingArray.length - filteringArray.length + 1][filteringArray.length][];

Why do my loops stop early when iterating through and array

So I am trying to iterate through a 4 by 3 array of objects and set the value of each object according to user input, but I've run into a problem where the iteration through the array stop at 6 instead of the total 12. I've tried a few way of writing the iterators but they always fail. This is the code.
Card[][] field = new Card[3][2];
void setvals(){
Scanner scanner = new Scanner(System.in);
for(int row= 0; row < field.length; row++){
for(int col = 0; col < field[row].length; col++) {
String input = scanner.nextLine();
field[row][col] = new Card();
field[row][col].makeCard(input);
}
}
}
I have also tried <= instead of < but then it gives me array index out of bounds. I have no clue what the problem is.
Your problem is with the array:
Card[][] field = new Card[3][2];
You want the array to be 4 x 3, then set the dimensions as so:
Card[][] field = new Card[4][3];
The reason your code is not working, is since you currently have a 2 x 3 array, evaluating to 6 iterations. A 4 x 3 array would evaluate to 12 iterations, as you want.
You say:
So I am trying to iterate through a 4 by 3 array of objects...
And here is your array: Card[][] field = new Card[3][2];.
That is not a 4x3 array. It is a 3x2 array, which means there should be 6 iterations in your loop, which is what is happening. There is no error here.

Break large 2D array into multiple smaller 2D array using JAVA

I have a 2D array which consist of image pixels which its size depends on the size of the input image. I need to break it into smaller 9x9 arrays. To give a clearer picture, I try to illustrate the situation:
//The number of rows and columns of the smallerArray will look something like this:
It should copy them from the imagePixels array iterating through each 8 columns, then move on to the next 8 rows.
1st small 2nd small 3rd small and so on..
array: array: array:
012345678 91011121314151617 181920212223242526 ....
0 0 0
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
8 8 8
Then move on to next 8 rows:
012345678 91011121314151617 181920212223242526 ....
9 9 9
10 10 10
11 11 11
12 12 12
13 13 13
14 14 14
15 15 15
16 16 16
17 17 17
.
.
.
I have done the following code but could not get my logic right. How can I stop the iteration:
Copy up until the 9th column or row, store it in an array, resume copying on the 10th column/row, stop when it reaches 9 column/row after, store it in another array, and keep on doing that till it finishes copying the imagePixels array.
I tried to store the arrays in an ArrayList so it would be easier for me to manipulate and do calculation stuffs with all the smallerArrays.
ArrayList<double[][]> collectionofSmallArrays = new ArrayList();
double[][] imagePixels = new double[1600][1000]; //Lets say this is the size of the image
double[][] smallerArray = new double[9][9];
for(int a = 0; a<smallerArray.length; a++)
{
for(int b =0; b<smallerArray[a].length; b++)
{
for(int c=0; c<imagePixels.length; c++)
{
for(int d=0; d<imagePixels[c].length; d++)
{
smallerArray[a][b] = imagePixels[c][d];
...(code to stop the iteration if it reaches 9, store it in array then resume where it stops with another new array)
collectionofSmallArrays.add(smallerArray);
}
}
}
}
Can anyone work around the code to achieve the expected result? Appreciate it.
You should probably provide more context information. Saying that an array of double values represents pixels sounds dubios. If you are working with images, then you might find solutions on a completely different level of abstraction (I'm thinking about BufferedImage#createSubImage here).
However, to answer the question: You should break the task up into smaller parts. Particularly, it might be easier to implement two methods:
One method that receives an input array, some coordinates, and an output array, and that copies the data from the specified coordinates of the input array to the output array
One method that calls the above mentioned method with the appropriate coordinates to split the whole array into the parts of the desired size.
In pseudocode:
for (each coordinates (9*r,9*c)) {
copy the rectange (9*r,9*c)-(9*r+9,9*c+9) of the input array into an array
A very simple implementation/test is shown in the following example. Note that this could be generalized and improved, but I think it shows the basic idea:
import java.util.ArrayList;
import java.util.List;
public class SubArrayTest
{
public static void main(String[] args)
{
double inputArray[][] = createInputArray(160, 100);
System.out.println("inputArray: "+toString(inputArray));
List<double[][]> subArrays = createSubArrays(inputArray, 9, 9);
for (double subArray[][] : subArrays)
{
System.out.println("subArray:\n"+toString(subArray));
}
}
private static List<double[][]> createSubArrays(
double inputArray[][], int subRows, int subCols)
{
List<double[][]> subArrays = new ArrayList<double[][]>();
for (int r=0; r<inputArray.length; r+=subRows)
{
for (int c=0; c<inputArray[r].length; c+=subCols)
{
double subArray[][] = new double[subRows][subCols];
fillSubArray(inputArray, r, c, subArray);
subArrays.add(subArray);
}
}
return subArrays;
}
private static void fillSubArray(
double[][] inputArray, int r0, int c0, double subArray[][])
{
for (int r=0; r<subArray.length; r++)
{
for (int c=0; c<subArray[r].length; c++)
{
int ir = r0 + r;
int ic = c0 + c;
if (ir < inputArray.length &&
ic < inputArray[ir].length)
{
subArray[r][c] = inputArray[ir][ic];
}
}
}
}
//===Test methods=========================================================
private static double[][] createInputArray(int rows, int cols)
{
double array[][] = new double[rows][cols];
for (int r=0; r<array.length; r++)
{
for (int c=0; c<array[r].length; c++)
{
array[r][c] = r*100+c;
}
}
return array;
}
private static String toString(double array[][])
{
String format = "%7.1f";
StringBuilder sb = new StringBuilder();
for (int r=0; r<array.length; r++)
{
for (int c=0; c<array[r].length; c++)
{
sb.append(String.format(format, array[r][c])+" ");
}
sb.append("\n");
}
return sb.toString();
}
}
Side notes:
You should always declare variables with their interface type. This means that you should not write
ArrayList<String> x = new ArrayList<String>();
but always
List<String> x = new ArrayList<String>();
In the posted code, you seemed to always add the same instance of the sub-array to the list. This means that in the end you would have many instances of the same array in the list, all with the same content. Somewhere in between you have to create a new double[9][9] array.
smallerArray[a][b] = imagePixels[c][d] line looks strange. You reuse same array instance. Your output array list will contain multiple reference to same array.
You cannot reuse smallerArray. Create the instance inside the for loop and store the size in a constant.
I think a map with some corner coordinates as a key would be far better than a list for storing your results.
What happens if the length or width or your image is not divisible by 9?

extending two 2D Arrays into a larger one

I have two java 2D arrays(array1 and array2), both of type Double which I would like to join together.
array1 and array2 are n-by-d matrices. the n-rows for each array can vary from eachother but the d-columns are always the same.
The question is: i have to concatenate array2 after the first one.(at best into the new outputMatrix)
Example:
array1:
2 3
6 5
4 7
array2:
1 5
3 7
Output Array (n-array1 + n-array2)-by-d:
2 3
6 5
4 7
1 5
3 7
My idea was to copy array1 into the outputMatrix, and then fill the continuation of it with array2.
My Java code for merging the two arrays(that are already implemented) looks like:
private static double[][] outputMatrix ;
outputMatrix = new double[array1.length+array2.length][array1[0].length];
for (int column = 0; column < array1[0].length; column++) {
for (int row = 0; row < (array1.length); row++) {
outputMatrix[row][column] = array1[row][column];
}
}
for (int column = 0; column < array1[0].length; column++) {
for (int row = array1.length; row < (array1.length+ array2.length); row++) {
outputMatrix[row][column] = array2[row][column]; //error here as array2 starts iterating at field [4][0] which isnt defined in the example
}
}
Your indices are wrong.
Should be
for (int column = 0; column < array1[0].length; column++) {
for (int row = 0; row < array2.length; row++) {
outputMatrix[row+array1.length][column] = array2[row][column];
}
}
since array2 has indices from 0 to array2.length-1.
So what's happening is that when you are trying to transfer the data from the second array into the outputMatric variable, you go out of bounds in the second array (array2). This is due to the fact that you're outputMatrix is trying to put a value at [array1.length + row][array1.length + column] and the second array isn't as big as that one. On top of that, your row index is wrong, you need to add the array1 length to make up for it or start the for loop's row variable at that spot. I elected just to add the length into the storing of the variable. So, you should make your code:
outputMatrix[row + array1.length][column] = array2[row - array1.length][column - array1[0].length];

null last element in 2D array

I have the following 2D array:
private static Object[][] myClass = new Object[6][5];
and I am looking to null the last element in the array (myClass[lastIndex][all indexes] = null) using the following code:
for(int y = 0;y < 5;y++) {
myClass[5][y] = null;
}
However it seems to be deleting the last two elements in the array, what is causing this?
EDIT:
array print out before delete:
one
1
1
1
1.0
two
2
2
2
2.0
three
3
3
3
3.0
four
4
4
4
4.0
five
5
5
5
5.0
six
6
6
6
6.0
After "deleteing" element one(In practise I want to "delete" element one by copying all the elements down one index and setting the last to null):
two
2
2
2
2.0
three
3
3
3
3.0
four
4
4
4
4.0
five
5
5
5
5.0
null
null
null
null
null
null
null
null
null
null
My full delete code:
public void deleteStudent(int studentChoice) {
for(int i = studentChoice;i < myClass.length - 1;i++) {
myClass[i] = myClass[i+1];
}
myClassCount = myClassCount - 1;
for(int y = 0;y < 5;y++) {
myClass[5][y] = null;
}
}
int studentChoice is the index of the array.
myClassCount is a variable that's incremented/de-incremented as elements are added/deletted
This is a subtle problem:
When you copy down, the references are copied, not the values in the array so that in the last step, because you don't overwrite myClass[5], myClass[5] == myClass[4] so that any changes you then make to any element in myClass[5] are replicated in myClass[4] as they are the same object! Therefore when you null each object in myClass[5], you are nulling everything in myClass[4] aswell. This can be avoided by copying the individual values down, rather than just the arrays.
You can copy the values down like this:
for(int i = studentChoice;i < myClass.length - 1;i++) {
for(int y = 0;y < 5;y ++){
myClass[i][y] = myClass[i+1][y];
}
}
As a side note, this behavior can be demonstrated by the following:
Object[] array1 = {1};
Object[] array2 = array1;
array2[0] = 2;
System.out.println(array1[0]);//Prints 2

Categories