Why do I get an "java.lang.ArrayIndexOutOfBoundsException: 0" - java

What is wrong here? I get an runtime error when I run the code in Netbeans saying "java.lang.ArrayIndexOutOfBoundsException: 0"
I found out it means something like "the value does not exist" - but that is what I am trying to do - to let the user define the values for the array size. Help, please.
public static void main(String[] args) {
int row = 0;
int colum = 0;
//Declare 2d array
int [][] matrix = new int [row][colum];
//Create input for array size
Scanner input = new Scanner(System.in);
System.out.println("Enter " + matrix[row].length + " rows and " + matrix[colum].length + " colums: ");
for (row = 0; row < matrix.length; row++) {
for (colum = 0; colum < matrix[row].length ; colum++) {
matrix[row][colum] = input.nextInt();
//Input variables to array
//Print the array
for (row = 0; row < matrix.length; row++ ) {
for (colum = 0; colum < matrix[row].length; colum++ ) {
System.out.println(matrix[row][colum] + "");
}
System.out.println();
}
}
}
}
}

Two problems. You need to initialize row and column with non-zero values:
int row = 3;
int colum = 4;
You're not referencing the dimensions of the matrix correctly, you want:
System.out.println("Enter " + matrix.length + " rows and "
+ matrix[0].length + " colums: ");
There are a few more bad references further down. You could of course just use your row and column variables instead of getting the lengths from the matrix though.

For your case
int [][] matrix = new int [0][0];
Means with no element , index starts from 0, where the size you specify starts from 1
Go for ArrayList if you want dynamic array

Your array has 0 elements - you're trying to access the first (with index 0) - which is out of bounds.

You are creating an array of arrays that has size 0 in both dimensions:
int row = 0;
int colum = 0;
//Declare 2d array
int [][] matrix = new int [row][colum];
If you try to index this you will get an ArrayIndexOutOfBoundsException.
Set row and colum to something > 0.
Arrays in Java have a fixed size. Once you have created an array, you can't change the size of it. If you need to change the size at runtime, use a collection class (for example an ArrayList) instead of an array.

int row = 0;
int colum = 0;
int [][] matrix = new int [row][colum];
The declared array has zero rows and zero columns. You can't store anything in it.
The exception occurs here:
matrix[row].length
with row=0 because it is the number of columns of the first row (arrays are zero based!) which doesn't exist.

Your problem is that you're setting row and column to 0, then you create a two-dimensional array of size 0 in both directions, and then this:
matrix[row].length
fails because there is no entry at index 0 - it would require the array to have at least size 1.

Related

Finding sum of a row of A 2D array, out of bounds error when column number is greater

I know theres a lot of questions like these but I can't seem to find the error in this. I'm trying to find the sum of a row inputed by a user in a 2D Array. The array size is based on the user input.
//Ask user for number of rows and columns in 2D Array
System.out.println("Enter Number of Rows");
int rows = input.nextInt();
System.out.println("Enter Number if Columns");
int columns = input.nextInt();
int[][] array = new int[rows][columns];
//loop through array to set values to random number from 1-100
for(int i = 0; i < array.length; i++){
for(int j = 0; j < array[i].length; j++){
array[i][j] = generator.nextInt(100)+1;//sets random numbers to the element of array
System.out.print(array[i][j]+" \t");
}
System.out.println();//next row of array
}
if(userOpt == 5){
System.out.println("Enter Row Number");//ask user for a row number
int rowInput = input.nextInt();
//if row input is greater than the size of rows error check
if(rowInput >= rows){
System.out.println("Invalid, Out of Range");
}else{
int rowSum = rowSum(array, rowInput);//calls rowSum method
System.out.println("Sun of Chosen Row is: "+rowSum);
}
here's the method for row sum
public static int rowSum(int[][] array,int rowInput){
int rowSum = 0;
for(int i = 0; i < array[i].length; i++){//loops through length of array
rowSum = rowSum + array[rowInput][i];//add each element to row Sum
}
return(rowSum);
}
The error only comes when the column number entered by the user is greater than the number of rows.
Exception is thrown by
i < array[i].length
as in the 5th iteration you`re doing
i < array[4].length
but array only has 4 rows (0-3).
What you probably want is
i < array[0].length
as every row has the same length.
In rowSum(), simply change:
array[i].length
To:
array[rowInput].length
You could also write it as:
public static int rowSum(int[][] array, int rowInput){
int rowSum = 0;
int[] row = array[rowInput];
for(int i : row) {
rowSum = rowSum + i; //add each element to row Sum
}
return rowSum;
}
As every row in the 2D array is simply a 1D array and using the enhanced for loop syntax eliminates that type of error altogether since we don't care about the index positions of the values; we just want to add them up.
Side note: You have validation for rowInput that checks the upper bound:
//if row input is greater than the size of rows error check
if(rowInput >= rows){
This may or may not be "correct" as your prompt does not specify what the first row is. Should the user be using 0 or 1 as the first row? You should make that very clear to the user. If the user is treating 1 as the first row then you need to subtract one from their value so that it gets the correct row from the zero based Array in Java.
Side, side note: What about the lower bound!? Your code that gets the row number is:
int rowInput = input.nextInt();
This will happily accept -1 as input, but will cause your program to crash.

print index of 2 max values

My question is if I input two maxvalue numbers in array, ex. 100, 10, 100. How can i get the output to print both index numbers?
The output expected would be 100 on index 1 and index 3
the index has 1 added as I want the index to start at one not zero
Add this to initialization.
HashSet<Integer> maxIndices = new HashSet<Integer>();
Make a second pass through the mileage array and add any max values to the HashSet.
The other option is to use a HashMap where the first integer is the mileage and the second value is the positive integer of how many have been found.
Because it makes only one pass, it may be faster even though you are counting every mileage, not just the one that ends up being the largest. Whether it is will be, of course, dependent upon the data, the compiler, and environmental conditions at the time of execution.
For your return value, you'll either need a custom POJO Java Bean or you can use Pair<> or Tuple<>. (See Using Pairs or 2-tuples in Java.)
Just simple Java using a series of for loops. The below method will return a 2D int array with each row consisting of two columns, the highest array value and its' respective array index number.
public int[][] getAllMaxValues(int[] allValues) {
int maxVal = 0;
int counter = 0;
// Get the Max value in array...
for (int i = 0; i < allValues.length; i++) {
if (allValues[i] > maxVal) {
maxVal = allValues[i];
}
}
// How many of the same max values are there?
for (int i = 0; i < allValues.length; i++) {
if (allValues[i] == maxVal) {
counter++;
}
}
// Place all the max values and their respective
// indexes into a 2D int array...
int[][] result = new int[counter][2];
counter = 0;
for (int i = 0; i < allValues.length; i++) {
if (allValues[i] == maxVal) {
result[counter][0] = maxVal;
result[counter][1] = i;
counter++;
}
}
// Return the 2D Array.
return result;
}
How you might use this method:
int[] allMiles = {100, 10, 100, 60, 20, 100, 34, 66, 74};
int[][] a = getAllMaxValues(allMiles);
for (int i = 0; i < a.length; i++) {
System.out.println("Array max value of " + a[i][0] +
" is located at index: " + a[i][1]);
}
Console window would display:
Array max value of 100 is located at index: 0
Array max value of 100 is located at index: 2
Array max value of 100 is located at index: 5

Two dimentional array printing rows

Okay, so I need to print 10 rows from 1 to 10 and 15 columns in every row from 1 to 15 with lines in between numbers. The second subroutine runs on its own, but only prints 0's and the first subroutine is me trying to give value to rows and columns, but I know I'm doing it very wrong. Any help is appreciated
static int ROWS = 10;
static int COLUMNS = 15;
static int[][] myArray = new int[10][15];
static int i; // loops through the number of rows
static int j; // loops through the number of columns
static int num1 = 0;
static int num2 = 0;
public static void vlueArray() {
for (i = 1; i < ROWS; i++) {
myArray[i][j]= num1++;
for (j = 1; j < COLUMNS; j++) {
myArray[i][j] = num2++;
System.out.print(myArray[i][j]);
}
System.out.println("");
}
}
public static void display2DArray() {
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLUMNS; j++) {
System.out.print(myArray[i][j] + " | ");
}
System.out.println("");
System.out.println("_____________________________________________________________");
}
}
you have not initialized elements in array and that is why you are getting zero displayed because int values are always initialized by the compiler even if you don't initialize them. The default value of int is 0.
Initialize your 2D array like this:
int[][] myArray = new int[10][15]{{2,3},{3,5},..........};
Hope this helps.
There are two issues here. First, you don't have very good syntax, while the way you have this set up does work, let me give you a couple of tips about settings this up, and then we can fix your problem fairly easily.
Some general rules here:
You don't have to initialize loop variables in the class variables, just initialize them in the loop structure (I'll show you this below).
Use the ROW and COLUMN in declaring your array, it helps make sure the array length values are the same throughout.
Your loop for creating the values in vlueArray is incorrect. I'll show you some correct formatting for placing these values below.
When you array is initialized, each place in the array (if it is an integer array) is automatically given a value of zero. You can change this, but since the first method doesn't run correctly, printing the values in the array without changing them will give the array of zeros.
Now, it seems like you want to just have 1 - 15 on 10 different rows. To do this, you only need one variable, so my response code will only have one variable, but if this isn't what you want, I'd be glad to help you get a different setup.
So now that you have a little bit of background information, let's get you some working code.
static int ROWS = 10; //Your row count.
static int COLUMNS = 15; //Your column count.
static int num = 0; //Our number.
//Using the constants to make sure rows and columns values match everywhere.
static int[][] myArray = new int[ROWS][COLUMNS];
public static void fillArray() {
//Initializing the loop variables in the loop is the common practice.
//Also, since the first index is zero, the loop needs to start at 0, not 1.
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLUMNS; j++) {
//If you want 0 - 14, use `num++`.
//If you want 1-15, use `++num`.
myArray[i][j] = num++;
}
num = 0; //This sets num back to zero after cycling through a whole row.
}
//Your display method works just fine.
public static void display2DArray() {
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLUMNS; j++) {
System.out.print(myArray[i][j] + " | ");
}
System.out.println("");
System.out.println("_____________________________________________________________");
}

Printing 3D Array

I am trying to print arrays before and after they are filled with user given inputs. Therefore, this would be the output if the given size is 3:
//user inputs values for first matrix
Before adding:
Array [0] =
Array [1] =
Array [2] =
//add user inputs
After adding:
Array [0] = row 0 = [...]
row 1 = [...]
... depending on user given size of the first matrix
Array[1] = Array[2] =
//ask for inputs for second matrix
Before Adding
Array [0] = row 0 = [...]
row 1 = [...]
... depending on user given size of the first matrix
Array[1] = Array[2] =
After adding
Array [0] = row 0 = [...]
row 1 = [...]
... depending on user given size of the first matrix
Array[1] = row 0 = [...]
row 1 = [...]
... depending on user given size of the first matrix
Array[2] =
I wrote the following code to achieve this (In a class called ThreeDRayRunner):
public static void print(int [][][] array)
{
for (int i=0; i<array.length; i++ )
{
for (int x=0; x<array[i].length;x++)
{
System.out.println();
System.out.print("row "+ x);
for (int j=0; j<array[i][x].length;j++)
{
System.out.print (array[i][x][j]+ " ");
}
}
}
However,I get the following error:
Exception in thread "main" java.lang.NullPointerException
at ThreeDRay.print(ThreeDRay.java:13)
at ThreeDRayRunner.main(ThreeDRayRunner.java:41)
Also, in the runner I ask the user to input the integer that will be stored in the 3D Array. To do this I ask for the size and print the 3D Array when is empty and after the given numbers are added. This is my code for that:
Scanner keyboard = new Scanner(in);
out.print("How many matrices are you going to enter? ");
int s = keyboard.nextInt();
int[][][] d3= new int [s][][];
for(int i = 0; i < S; i++)
{
out.print("What is the size of the matrix " + i + " ? ");
int size = keyboard.nextInt();
int[][] mat = new int[size][size];
out.println();
for(int r=0; r<mat.length; r++)
{
for(int c=0; c<mat[r].length; c++)
{
out.print("Enter a value for spot " + r + " - " + c );
mat[r][c]=keyboard.nextInt();
}
}
out.println("The array before setting mat at spot "+i);
ThreeDRay.print(d3);
d3[i] = mat;
out.println("The array after setting mat at spot "+i);
ThreeDRay.print(d3);
You are not instantiating the 2nd and 3rd dimensions of d3 Did you mean to do this line before your first print?
d3[i] = mat;
So it would look like this:
d3[i] = mat;
out.println("The array before setting mat at spot "+i);
ThreeDRay.print(d3);
Follow up:
It looks like you actually didn't want to set d3[i] before your first print. In that case make sure you 3 dimensions for d3 are all non-null since your print is going to print all of them and not only the one that you set to mat. Initialize your 2nd and 3rd dimensions (to 0) before you start.
int[][][] d3= new int [s][][];
for (int i=0; i < d3.length ;++i){
d3[i] = new int[0][0];
}

Java - How to join multiple values in a multidimensional array?

I'm beginner programmer, I have fallen into a rabbit hole trying to understand how to use arrays. I'm trying to create a table using multidimensional arrays and I am looking to create a table with 7 rows and 5 columns.
column 1 = will take values from the user input.This input is stored in an array.
column 2 = will print the highest input in that array.
column 3 = will print the lowest input in that array
column 4 = will print take the increment Total. i.e current input + previous input.
column 5 = will take the increment average. i.e Total/Index
Complete Code below
import java.util.Scanner;
public class Numbers {
public static void main(String[] args)
{
//----User Input - Add values to array ----//
Scanner keyboard = new Scanner(System.in);
int places = 7;
int [] values = new int [places];
int sum = 0;
System.out.println("Enter a Numbers:");
for (int count = 0; count < places; count++)
{
values[count] = keyboard.nextInt();
System.out.println(values[count]);
}
//----------------Total---------------------//
for (int numb : values)
{
sum = sum + numb;
}
System.out.println("\n Total:" + sum);
//----------Average------------------------/
double avg = 0;
if (values.length > 0)
{
avg = sum / values.length;
}
System.out.printf("\n Average:"+ avg);
//---------Table Start---------------------//
int [] [] table = new int [7][5];
for (int row =0; row < 7; row++)
for (int column = 0; column < 5; column++)
table [row][column] = getTable(column, column, column, column, avg);
System.out.println("\n\nIndex\tInput\tHigest\tLowest\tTotal\tAverage");
for (int row = 0; row < 7; row++)
{
System.out.print((row + 1) + " ");
for (int column = 0; column < 5; column++)
System.out.print("\t " + table[row][column] + " ");
System.out.println();
}
}
public static int getTable(int input, int highest, int lowest, int total, double average) {
/* TO DO:
* - add each user input from values array into Input column
*
* - add highest/lowest values in the Highest/Lowest column
*
* - add each of the array element total in Total column - this column should take previous Total plus current total.
* i.e Total = Total + Input
*
* - add Average - Current average value.
*/
return 0;
}
}
What I don't know is how to get my code to fill each of the rows using different values each time.
For Example:
Index 1
1st column take first value of the values array
2nd column: take highest value of the values array
3rd column: take lowest value of the values array
4th column: take previous element of values array plus the current value
5th column: take total/index
I know that may need to create a method to get my program to loop through but I just don't know how to do it. I've tried a few different ways, but I'm just getting confused. In the left corner of the screenshot below, is how the columns would look like. Notice how they are all returning 0, which I known that is coming from the getTable method that I created, which is doing just that.
Basically, in this code, you're looping over all the columns:
for (int row =0; row < 7; row++)
for (int column = 0; column < 5; column++)
table [row][column] = getTable(column, column, column, column, avg);
You don't want to do this. Looping over all the columns would make sense if you were doing pretty much the same thing with each column. But you're not. You want each column to have the result of a very different computation. So it would make more sense to say something like
for (int row = 0; row < table.length; row++) {
table[row][0] = getFirstValue(values);
table[row][1] = getHighestValue(values);
table[row][2] = getLowestValue(values);
...
and so on. (However, I don't really understand how "values" is supposed to be used. You're inputting one set of values, but you're creating a table with 7 rows based on that one set of values. Perhaps there's more things wrong with your code.)
Note a couple of things: (1) I replaced 7 with table.length in the loop. table.length is the number of rows, and will be 7. But if you change things to use a different number of rows, then using table.length means you don't have to change the for loop. (2) My code passes values as a parameter to the different methods, which is necessary because the methods will be making computations on the input values. Your code didn't pass values to getTable(), so there's no way getTable() could have performed any computations, since it didn't have the data.
The code could be improved further. One way would be to define constants in the class like
private static final int FIRST_VALUE_COLUMN = 0;
private static final int HIGHEST_VALUE_COLUMN = 1;
...
table[row][FIRST_VALUE_COLUMN] = getFirstValue(values);
table[row][HIGHEST_VALUE_COLUMN] = getHighestValue(values);
which would be more readable.
A more significant improvement would be not to use a 2-D array at all. Since you have five values with different meanings, the normal approach in Java would be to create a class with five instance variables to hold the computed data:
public class ComputedData {
private int firstValue;
private int highestValue;
private int lowestValue;
public void setFirstValue(int firstValue) {
this.firstValue = firstValue;
}
public int getFirstValue() {
return firstValue;
}
// similarly for other fields
}
table would then be a 1-dimensional array of ComputedData.
This is better because now you don't have to assign meaningless column numbers to different computed values. Instead, the names tell you just what each computed value is. Also, it means you can add new values later that don't have to be int. With an array, all elements in the array have to be the same type (you can use Object which can then hold a value of any type, but that can make the code messier). In fact, you may decide later that the "average" should be a double instead of an int since averages of integers aren't always integers. You can make this change pretty easily by changing the type of an instance variable in the ComputedData class. If you use an array, though, this kind of change gets pretty complicated.

Categories

Resources