Why do my loops stop early when iterating through and array - java

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.

Related

Java Copying Data from Array Rather than Reference

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

Matrix filler block

In my class we have to make a matrix filler program but I have gotten very confused on how to do so by using the user input and I don't know how to at all. Iv'e tried to start coding but can't get past step 1.
package question4;
import java.util.Random;
import java.util.Scanner;
import java.util.Arrays;
public class MatrixFiller {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Size of Matrix: ");
Random ranGen = new Random();
int matrixSize = input.nextInt();
int a = matrixSize * matrixSize;
input.close();
int[][] myMatrix = new int[matrixSize][matrixSize];
for (int x = 0; x < matrixSize; x++) {
for (int y = 0; y < matrixSize; y++) {
myMatrix[x][y] = ranGen.nextInt(a);
System.out.print(Integer.toString(myMatrix[x][y]) + " ");
}
System.out.print("\n");
}
}
}
so i fixed the code and was wandering how can i add the zero inferno of the number like 1 and 2 so it comes out 01 and 02, do i need an if loop so that it only checks numbers less then 10?
By your example code it seems that what you are missing is basic syntax knowledge. Let me refresh your memory on arrays at the most basic level with simple language.
Arrays are like a multi-dimensional list of variables of some type.
You choose the type of variables when you declare the array.
The amount of variables which an array can hold is a constant number (the length of the array) which is defined when is is initialized.
An array can also have more than one dimensions. You set the number of dimensions when you declare the array. Think of a 1 dimensional array as a list, 2 dimensions would turn the list into a matrix. In this case, you need to set the length of each dimension (when you initialize). So, if the length of the 2 dimensions is the same you get a square, otherwise you get a rectangle.
Here is some code to go along with this:
int[] myArray;
Here I declared a 1 dimensional array which holds ints.
myArray = new int[6];
Here I initialized my array and set the length of the dimension to 6.
int[] myArray2 = new int[7];
I can also do them on the same line.
long[][] myMatrix = new long[3][2];
Here I declared a 2 dimensional array which holds longs. The lengths of the dimensions are 3 and 2, so it looks like this when you imagine it:
_ _
_ _
_ _
Now we wan to access the array at a certain position. This is done by specifying the array name and the position in each dimension you want to access, like this:
myMatrix[0][1] = 63;
Remember! The position start counting from 0, so a 2 by 3 array would have the first dimension values 0 and 1; and the second dimension values 0, 1 and 2.
Now let's iterate over an array and put the number 6 in all of its slots:
int[][] exmaple = new int[3][3]; // 2 dim. array of ints with size 3 by 3.
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
example[x][y] = 6;
}
}
Not sure if you need this, but I will mention a few additional notes:
You can initialize an array with values directly and then you don't need to specify the dimensions' lengths:
int[][] array = new int[][] {{1 ,2}, {5, 65}}; // 2 by 2
You can get the length of a dimension of an array by the syntax
array.length;
array[0].length;
array[1].length;
// etc.
These return an int which you can use as a bound when looping:
for (int i = 0; i < array.length; i++) {
// ...
}

How to insert a number into an array in java

Ok I am trying to do the following using an array.
Say I have one array
1 4 3 7 8
and at index 1 I want to place a 2 to get the following
1 2 4 3 7 8
How do I do this I think I have to make one array to keep everything before the index, one array to keep everything after the index.
And the add one more element to the array with everything before the index. The create a new longer array with everything before the index and everything after the index.
But I cannot seem to do it. This be what I tried.
//this program will test out how to replace an array with more stuff
public class Raton
{
public static void main(String[] args)
{
int[] gato={1,4,3,7,8};
int[] perro = new int[gato.length+1];
int[] biggie = new int[gato.length];
int index=2; //store item index 2
System.out.println("the contents of gato are ");
for(int i=0; i<gato.length;i++)
{
System.out.println(gato[i]);
}
for(int i=0;i<gato.length;i++)
{
if(i<index)
{
perro[i]=gato[i];
}
else
{
int red=0;
biggie[red]=gato[i];
red++;
}
}
//put two in the new place
for(int i=0;i<perro.length;i++)
{
System.out.println(" \n the contents of peero are " + perro[i]);
}
for(int i=0; i<biggie.length;i++)
{
System.out.println("\nthe contents of biggie are " + biggie[i]);
}
}
}
First you need to get both the new number and new index.
int newNumber = 2;
int newIndex = 1;
Create the new array with size+1 of old array
int[] gato = {1,4,3,7,8}; //old array
int[] perro = new int[gato.length+1]; //new array
Then keep track of of two counters. j for old array and i for new array.
int j = 0;
for(int i = 0; i<perro.length; i++){
if(i == newIndex){
perro[i] = newNumber;
}
else{
perro[i] = gato[j];
j++;
}
}
Here's a test run. This solution is assuming you have a constraint where you can only use arrays (not ArrayList or any other prebuilt classes in Java)
Use an ArrayList<Integer> instead of arrays, they allow easy insertion of new elements, and arraylists allow that at specific indices too.
int[] gato={1,4,3,7,8};
List<Integer> list = new ArrayList<>(Arrays.asList(gato));
list.add(1, 2);
I haven't tested this code, but something similar should do the trick.
public class Raton {
public static void main(String[] args) {
int[] originalArray = {1,4,3,7,8};
int[] modifiedArray = new int[originalArray.length + 1];
int index = 2;
for(int i = 0; i < (originalArray.length + 1); i++) {
if(i==1) {
modifiedArray[i] = index;
}
else if(i < 1){
modifiedArray[i] = originalArray[i];
}
else {
modifiedArray[i] = originalArray[i-1];
}
}
}
}
Try to look at the "before" and "after" arrays:
Before
┌─┬─┬─┬─┬─┐
│1│4│3│7│8│
└─┴─┴─┴─┴─┘
0 1 2 3 4
After
┌─┬─┬─┬─┬─┬─┐
│1│2│4│3│7│8│
└─┴─┴─┴─┴─┴─┘
0 1 2 3 4 5
One thing you already noticed is that you need a target array that is 1 bigger than the original array. That's correct.
But you have several problems in your program.
You copy all the parts that are before the index to perro. Since perro is your target array (the one bigger than the original), you have to make sure that everything gets copied to it. But instead, you only copy the parts that are before the index.
You want to place the 2 at index 1. But you wrote index=2. This means that both the 1 and 4 will be copied to perro consecutively. Your perro will look like this:
┌─┬─┬─┬─┬─┬─┐
│1│4│0│0│0│0│
└─┴─┴─┴─┴─┴─┘
0 1 2 3 4 5
and this means that you didn't put the 2 in the place you wanted it. That place is taken by the 4.
You try to copy the numbers after the index to biggie. But you are doing this using red. And in each iteration of the loop, you set red=0 again. So the only place in biggie that will change is 0, and that place will get all the numbers, and the last one will stay. So your biggie will be:
┌─┬─┬─┬─┬─┐
│8│0│0│0│0│
└─┴─┴─┴─┴─┘
0 1 2 3 4
You don't put the 2 anywhere!
You don't copy things from biggie to perro so you don`t get all the parts of the array together.
So let's look at our before and after arrays again:
Before
┌─┬─┬─┬─┬─┐
│1│4│3│7│8│
└─┴─┴─┴─┴─┘
0 1 2 3 4
After
┌─┬─┬─┬─┬─┬─┐
│1│2│4│3│7│8│
└─┴─┴─┴─┴─┴─┘
0 1 2 3 4 5
So first, we have to remember that the index we want to change is 1, not 2. Now look at the after array. You notice that there are three types of numbers:
Ones that stayed in the same place (the 1)
Ones that were added (the 2)
Ones that moved one place to the right (4,3,7,8)
How do we know which of the original numbers "stay" and which ones "move"? It's easy. The ones whose index is less than index (remember, it's 1!), that is, the one at index 0, stays.
All the others (including the one that is in the index itself!) have to move to a new place. The place is their old index + 1.
So your program should look like this:
Prepare an array whose size is one bigger than the original (like your perro).
Loop on all the indexes in the old array. Suppose the loop variable is i.
If i is less than the index, copy the number at index i from the original array to the new array at the same index, that is, at i.
For all other cases, copy the number at index i from the original array to the new array, but moved by one place. That is, i+1. There is no need for another variable or a ++ here.
When you finish that loop, your array will look like:
┌─┬─┬─┬─┬─┬─┐
│1│0│4│3│7│8│
└─┴─┴─┴─┴─┴─┘
0 1 2 3 4 5
Now don't forget to put your actual 2 there, at the index index!
Note: please give your variables meaningful names. I'm not sure, perhaps the names are meaningful in your native language, but biggie and red seem to be words in English, but they don't help us understand what these variables do. Try to use variable names that describe the function of the variable. Like original, target, temporary, nextIndex etc.
I think this is a clean and simple solution :
public static void main(String[] args) {
int[] gato = {1, 4, 3, 7, 8};
int index = 2; //store item index 2
System.out.println("the contents of gato are ");
for (int i = 0; i < gato.length; i++) {
System.out.println(gato[i]);
}
gato = Arrays.copyOf(gato, gato.length + 1);
for (int i = gato.length - 1; i > index; i--) {
gato[i] = gato[i - 1];
}
//put the element in the array
gato[index] = 2;
for (int i = 0; i < gato.length; i++) {
System.out.println(gato[i]);
}
}

Adding each value to an integer array

Can you help me with my problem? I need to add values to my int array but all I get is an ArrayIndexOutOfBoundsException.
public static void numberSort(){
int quantity = 0;
int[] values = new int[quantity];
int allocate = 0;
quantity = Integer.parseInt(JOptionPane.showInputDialog("How many values do you wish to sort? : "));
for(int x = 0; x <= values.length; x++){
allocate = Integer.parseInt(JOptionPane.showInputDialog("Values you want to sort : "));
values[allocate] = x;
System.out.println(values[x]);
}
int quantity = 0;
int[] values = new int[quantity];
You're allocating an array with 0 locations, which is effectively a zero-length array. This means that it really doesn't have any valid locations, so you can't store anything into it. This is why you're getting an ArrayIndexOutOfBounds exception when you attempt to store anything inside the array.
You will have to move the line where you allocate values to the line after the line where you read in the value of quantity.
Your next problem is your for loop:
for(int x = 0; x <= values.length; x++)
Array indices run from 0 to array.length - 1. So typically the terminating condition for the for loop is x < values.length. If this was your code, you wouldn't have seen this exception. However, even if you fix this to make quantity a non-zero value, you will get the exception when you attempt to fill the array since values[array.length] is out of bounds. So you will have to change your for loop to:
for(int x = 0; x < values.length; x++)
I also noticed that you have values[allocate] = x;. What you want is values[x] = allocate;, since you want the xth element of the array.
This line is your problem
int quantity = 0;
int[] values = new int[quantity];
You are creating an array with length 0. The length of an array is established when the array is created. After creation, its length is fixed.
Read more in tutorials: Arrays
For quick fix in your code just init your array after quantity
int quantity = Integer.parseInt(JOptionPane.showInputDialog("How many values do you wish to sort? : "));
int[] values = new int[quantity];
And in for loop change <= to < cause arrays starts in 0.
for(int x = 0; x < values.length; x++){
allocate = ...
values[x] = allocate; // you want to allocate in position "x" allocate
}
Aside from creating an array of 0 length, your for loop end condition is incorrect. You wrote x <= values.length, but you should write x < values.length. Since arrays in Java are 0-indexed, that means the valid range of indices are 0 to values.length - 1.
I count three errors in there. The most significant one:
for(int x = 0; x <= values.length; x++){
Java arrays index from zero - that means that for example an array with length of 5 has indexes 0, 1, 2, 3 and 4. Anything beyond that in either direction results in the ArrayIndexOutOfBoundsException. Because you use <=, you read one value beyond what's allowed. Replace it with <.
Also, you initialize your array to size zero. That means you can't really use it. Initialize your array with quantity only once quantity has the correct value!
Finally, I believe you want values[x] = allocate;, not vice versa.

2D array and an out of bounds exception

The last for loop will compile but it won't run. It says that array index out of bounds exception:17. I just want to add a ColorRectangles (subclass of ColorShape) to the 1-8 columns in the 17'th row
private ColorShape[][] _tiles;
public GamePanel()
{
_tiles = new ColorShape[8][17];
for (int i = 0; i<16; i++){
for(int j=0; j<8;j++){
_tiles[j][i] = null;
}
}
for (int j=0; j<8;j++){
_tiles[j][17] = new ColorRectangle(Color.BLACK);
}
}
Your array size is 17. Arrays are zero-indexed. This means your maximum array index for your second dimension is actually 16, not 17.
Either change your reference to tiles to:
_tiles[j][16] = new ColorRectangle(Color.BLACK);
OR make your _tiles array bigger like so:
_tiles = new ColorShape[8][18];
Either will fix this problem.
May I also suggest that your game panel object accept 2 dimensions, width and height. This makes your class more useable should you decide to use it again, or change its dimensions. Avoid hardcoding values whenever appropriate. Here it would be most appropriate.
Here's a rewrite for you:
private ColorShape[][] _tiles;
public GamePanel(int width, int height)
{
_tiles = new ColorShape[width][height];
for (int i = 0; i<height; i++){
for(int j=0; j<width;j++){
_tiles[j][i] = null;
}
}
for (int j=0; j<width;j++){
_tiles[j][tiles[j].length-1] = new ColorRectangle(Color.BLACK);
}
}
And here's how you would use it in your case:
GamePanel panel = new GamePanel(8, 17);
But you can always easily change your panels dimensions now!
GamePanel panel = new GamePanel(100,100);
Nifty huh?
This:
_tiles[j][17] = new ColorRectangle(Color.BLACK);
17 is not a valid index for your array since you sized it as [8][17]. Indices are from 0...length - 1, so in your case, up to 16. This is because arrays in Java (and any reasonable programming language) are zero-indexed. Thus, replace with
_tiles[j][16] = new ColorRectangle(Color.BLACK);
and at least you won't get an ArrayIndexOutOfBoundsException.
I just want to add a ColorRectangles (subclass of ColorShape) to the 1-8 columns in the 17'th row
See, in a zero-based indexing scheme, the 17th row is the row with index 16.
The first row corresponds to that with index 0. The second row corresponds to that with index 1. Etc. In general, the nth row corresponds to that with index n - 1 and a row with index n is actually the (n + 1)th row (assuming 0 <= n < length - 1).
Your problem is here:
_tiles[j][17] = new ColorRectangle(Color.BLACK);
You should have this instead (note that arrays are zero-indexed, so 17th column is at index 16):
_tiles[j][16] = new ColorRectangle(Color.BLACK);
In java, indexing starts from zero (0);
private ColorShape[][] _tiles;
public GamePanel()
{
_tiles = new ColorShape[8][18]; // new dim is 18 so last index is 17
for (int i = 0; i<18; i++){
for(int j=0; j<8;j++){
_tiles[j][i] = null;
}
}
for (int j=0; j<8;j++){
_tiles[j][17] = new ColorRectangle(Color.BLACK); //17 was out of bounds
}
}
The length of your array is [8][17] but the indexes go from [0] to [16].
Therefor replace
_tiles[j][17] = new ColorRectangle(Color.BLACK);
with
_tiles[j][16] = new ColorRectangle(Color.BLACK);
You're declaring your array with 8 fields in x range and 17 fields in y range in your code:
_tiles = new ColorShape[8][17];
Because you start counting from zero in the IT, the range is from zero to sixteen (0-16).
So if you want the last field of the array, you have to use the field 16 (_tiles[j][16]).
The code should be:
_tiles[j][16] = new ColorRectangle(Color.BLACK);
The whole thing is called zero-based-numbering/index.
You might also have a bug for the first loop.
Instead of
for (int i = 0; i<16; i++)
it should be
for (int i = 0; i<17; i++)
Arrays are zero-indexed meaning the starting index is 0 up to length-1.
So, in your case, it is up to 16.
For your second loop, it should be
_tiles[j][16] = new ColorRectangle(Color.BLACK);
According to the JLS (Array Access) - All arrays are 0-origin. An array with length n can be indexed by the integers 0 to n-1.
So if you initialize an array like you did _tiles = new ColorShape[8][17];. In order to access you need to do it by 0 to 7 and 0 to 16.
Now, with _tiles[j][17] = new ColorRectangle(Color.BLACK); you are trying to access something with is outside the array you have initialized and therefore you get java.lang.ArrayIndexOutOfBoundsException.

Categories