Why am I getting ArrayIndexOutOfBoundsException? - java

So I got this assignment while my teacher is away, and basically I have to make a student project. The student has a name, marks, and average. To calculate the average I decided to store the marks inside a int[] array.
public void addQuiz(int m)
{
int l = (marks.length);
marks[l] = m;
}
int[] marks = new int[8];
But when I run the function:
student.addQuiz(90);
I get:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 8
Any help?
I'm not sure what the int[8] part does but it was in the tutorial I followed and it would give me a null pointer without it. There are eight marks in total so I just made it 8.

You can't dynamically add things to an array. You should use an array list instead.
Arraylist<Integer> marks = new ArrayList<Integer>();
then in your addQuiz method:
public void addQuiz(int m) {
marks.add(m)
}
You'll probably also need to change your method for calculating the average a bit, but that should be trivial and I'll leave it to you.

The error says: ArrayIndexOutOfBoundsException: 8
You have an array with 8 elements, indexed from 0 to 7 (inclusive). This array has a length of 8, and you are actually trying to access marks[8], when you only can go up to 7.

In Java, Array index starts from '0'. so, you cannot access the index of the array equal to the length of the array.if your arrays length is '8', then the last index of the array is '7' not '8'. if you are trying to access the illegal index of the array, then ArrayIndexOutOfBoundException is thrown. the code should be changed to
public void addQuiz(int m)
{
int l = (marks.length); //assuming marks is an array of length '8'
marks[l-1] = m; //index is 7 now
}
To calculate the average, you need to sum up the contents of the array (provided all the values are of int values) and then divided by the lenght of the array
int sum = 0;
int avg = 0;
for(int i=0; i<array.length;i++){
sum =sum+array[i];
}
avg = sum/array.length;
Hope this gives an idea

Use Arraylist<Integer> and then you can add to the list dynamically

There is not index in this array for this marks[l] = m;. use marks[l-1] = m;

You can call this for loop in main for getting marks 8 times.
for(int i=0;i<8;i++)
student.addQuiz(<marks you want to enter>, i);
You can define addQuiz function like below
public void addQuiz(int m, int arrayIndex)
{
marks[arrayIndex] = m;
}
int[] marks = new int[8]; //this will be as it is
These are minimal changes. You can make your code better by passing array marks to addQuiz as a parameter. But this will also work, its just that this is not the best way to write code.

Related

Can array's index be negative number in Java?

public static void main(String[] args) {
int[] a = new int[10];
a[1] =2;
a[-1] = -2;
a[0] = 0;
System.out.println(a[-1]);
}
I write codes above, editor didn't judge it illegal, but when I run it, it give me
"Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1"
So is negative number index in java is illegal all the time? Or there's some special situation can let array's index be negative number?
Let's have a look at Oracle's documentation here. This is what it says:
An array object contains a number of variables. The number of variables may be zero, in which case the array is said to be empty. The variables contained in an array have no names; instead they are referenced by array access expressions that use non-negative integer index values. These variables are called the components of the array. If an array has n components, we say n is the length of the array; the components of the array are referenced using integer indices from 0 to n - 1, inclusive.
Also,
All array accesses are checked at run time; an attempt to use an index
that is less than zero or greater than or equal to the length of the
array causes an ArrayIndexOutOfBoundsException to be thrown.
To answer the question, no, index can't be negative.
There is no support in java for negative indices.
Last element can be accessed using
array[array.length-1] = lastElement;
In short, no, they cannot be negative.
From the docs(using get for example)
ArrayIndexOutOfBoundsException - If the specified index argument is negative, or if it is greater than or equal to the length of the specified array
So is negative number index in java is illegal all the time?
Yes.
Or there's some special situation can let array's index be a negative number?
You could write own array-like collection type where negative indices would be valid. It would be rather a domain-specific type because I can't think of any general applications.
A simple example would be
// define an anonymous class that overrides ArrayList's get behaviour
List<String> list = new ArrayList<String>() {
#Override
public String get(int index) {
return super.get(Math.abs(index));
}
};
list.add("a");
list.add("b");
System.out.println(list.get(-1)); // b
System.out.println(list.get(1)); // b
It's not what I would recommend you do. It's confusing and unusual for any Java developer.
Short answer: No.
Slightly less short answer: Array indices range from 0 to the length of the array minus 1.
E.g. :
int[] ints = new int[5];
ints[0] = 1; // fine
ints[4] = 1; // fine
ints[-1] = 1; // ArrayIndexOutOfBoundsException thrown
ints[5] = 1; // ArrayIndexOutOfBoundsException thrown
In java, Negative index can't be used. It is 0 based positive index. If used negative index then java will throw "ArrayIndexOutOfBoundsException" Exception.
arrays in java can not be indexed using negative numbers, the "problem" is that there is no such unsigned integers defined until now in java, so writing myArr[x] will compile as soon a x is a valid numerical index
As #Darshan Mehta's answer says, negative numbers are not allowed as array indexes. However, you can always write your own array class that allows negative indices.
Here's my example using generics.
public class ModuloArray<E> {
int size;
E[] array;
public ModuloArray(int size) {
if (size <= 0)
throw new RuntimeException("not positive");
this.size = size;
array = (E[]) new Object[size];
}
public ModuloArray(E... elements) {
if (elements == null)
throw new RuntimeException("null");
this.size = elements.length;
array = elements;
}
public E get(int index) {
return array[Math.floorMod(index, size)];
}
public void set(int index, E element) {
array[Math.floorMod(index, size)] = element;
}
}
public class Main {
public static void main(String[] args) {
System.out.println("*** ModuloArray with first constructor ***");
ModuloArray<String> myArray = new ModuloArray<>(3);
myArray.set(-1, "apple");
myArray.set(-2, "orange");
myArray.set(-3, "banana");
System.out.println(myArray.get(-3));
System.out.println(myArray.get(-2));
System.out.println(myArray.get(-1));
System.out.println(myArray.get(0));
System.out.println(myArray.get(1));
System.out.println(myArray.get(2));
System.out.println();
System.out.println("*** ModuloArray with second constructor ***");
ModuloArray<String> myArray2 = new ModuloArray<>("glazed donut", "chicken burger", "apple soda");
System.out.println(myArray2.get(-2));
System.out.println(myArray2.get(3));
}
}
The above example outputs:
*** ModuloArray with first constructor ***
banana
orange
apple
banana
orange
apple
*** ModuloArray with second constructor ***
chicken burger
glazed donut
Array indexes in Java are valid only if 0 <= index < array.length is true. However, because ModuloArray uses Math.floorMod(int x, int y) to access the array elements, any integer (including negative numbers) can be used as a valid index. This behavior is similar to how indexing works for lists in Python.

Error finding largest randomly generated double in ArrayList Java

I'm trying to get a program to work where I generate 1,000,000 random numbers between 0 and 1 and then find and print the largest number.
I've got the generator to work and managed to insert each double generated into an ArrayList but I cannot seem to figure out how to find the largest number in the list. At the moment the current code throws the error "java.lang.IndexOutOfBoundsException".
This is all probably due to me being new to the ArrayList and not being fluent with its commands and how it works but I would really appreciate some help on what I'm doing wrong here as I've been stuck for a while.
import java.util.ArrayList;
import java.util.Random;
public class milran {
public static void main(String[] args) {
Random r = new Random();
ArrayList<Double> myList = new ArrayList<Double>();
for (int i = 1; i<=1000000; i++){
double randomValue = 0.0+(1.0-0.0)*r.nextDouble();
myList.add(randomValue);
}
double max = myList.get(1);
for (int z=2; z<=myList.size(); z++){
double test = myList.get(z);
if (test>max){
max = test;
}
}
System.out.println(max);
}
}
First of all take a look at the docs for java.util.Collections and java.util.ArrayList.
Secondly, the ArrayIndexOutOfBoundsException is being triggered by this...
for (int z=2; z<=myList.size(); z++){
double test = myList.get(z);
...
}
This is because array indexing starts at 0, therefore the last element is myList.size() - 1. In other words, when z = myList.size(), it is out of bounds.
Also, in your first for loop, you are using i = 1; 1 <= 1000000. It makes much more sense to use i = 0; i < 1000000 as you can use i to touch each element in an array (or list).
for( i = 0; i < 1000000; i++ )
{
// do something with myArray[i]
}
Here's what I would do after the values have been inserted...
Sort the array: Collections.sort(myList);
Retrieve the last element: System.out.println( myList.get( myList.size() - 1 ) );
...and that's it.
If you need to implement the actual sort yourself then i'd consider using a primitive double array (double[]) rather than a Collection.
Otherwise, if you are using a collection, you can use a foreach loop.
for( Double d : myList ) // for each Double 'd' in myList
{
// do something with d
}
N.B. Another potential issue with this line in the second loop
double test = myList.get(z);
This automatic conversion from Double (object) to double (primitive) is called unboxing. There will be a performance cost, especially when repeated a million times. In the first loop you are converting the other way (autoboxing) – also a million times.
ArrayList start count its elements from 0. You need to replace myList.get(1) to myList.get(0), int z=2 to int z=1 and z<=myList.size() to z<myList.size().
This line: for (int z=2; z<=myList.size(); z++) { is wrong. It should be for (int z=1; z<myList.size(); z++) {.
This is because arrays and lists are 0 based, so a list of size 2 has 2 elements - index 0 and index 1. Currently you try to index into the element number equal to the size, which does not exist.
Along the same line, myList.get(1); should be myList.get(0);.
This is unrelated to your problem, but this line 0.0+(1.0-0.0)*r.nextDouble(); can be much more easily written as r.nextDouble();. I'm not sure what you were trying to do by doing 0 + 1 - 0.
As others have already pointed out, you have an error in your for-loop condition that causes the index to go out-of-bounds.
One way that you can avoid this in the future is by using Java's for-each loop syntax instead of trying to manage the index yourself.
for (Double test : myList) {
if (test>max){
max = test;
}
}
This syntax makes your intent much clearer than the traditional indexed for syntax and removes a point of potential error (managing the index and the bounds of the list) from your hands.

Get max length of row and column in java two dimensional array

What is the best and efficient way to get the maximum i, which is the number of rows and j, which is the number of columns, in a two dimensional array?
Hopefully, the time complexity can be lower than O(n) for every case. No loop here and can still find the maximum j.
For example, if I have an array like this one
[
[18,18,19,19,20,22,22,24,25,26],
[1,2,3],
[0,0,0,0]
]
Then I want to get i = 3 and j = 10 here as a result.
Can anyone help me?
You can avoid writing the loop yourself, but you can't avoid having a runtime of at least O(n), since "someone" needs to loop the source array.
Here is a possible way to do that in Java 8:
Arrays.stream(arr).map(row -> row.length).max(Integer::compare).get();
This returns the maximum length of a "row" in your 2d array:
10
Another version which avoids using the Comparator and therefore might be a bit easier to read:
Arrays.stream(arr).mapToInt(row -> row.length).max().getAsInt();
arr is supposed to be your source array.
Edit: the older version used .max(Integer::max), which is wrong and causes wrong results. See this answer for an explanation.
Assuming your array does not contain null values, you could write something like this:
private static final Comparator<int[]> lengthComparator = new Comparator<int[]> () {
#Override
public int compare(int[] o1, int[] o2) {
return o1.length - o2.length;
}
};
#Test
public void soArrayMaxLength() {
int[][] array = new int[][] {
{18,18,19,19,20, 22, 22, 24, 25,26},
{1,2,3},
{0,0,0,0}
};
int i = array.length;
Optional<int[]> longestArray =
Arrays.stream(array)
.max(lengthComparator);
int j = longestArray.isPresent() ? longestArray.get().length : 0;
System.out.println(String.format("i=%d j=%d", i, j));
}
If you happen to create a parallel stream from the array instead, you could speed up this even further.
Another option is to sort the array by length, the quicksort usually has an average complexity of O(n*log(n)) therefore this isn't faster;
int i = array.length;
Arrays.parallelSort(array, lengthComparator);
int j = array[i-1].length;
System.out.println(String.format("i=%d j=%d", i, j));
Your i is the number of rows, which is simply the length of the 2-D array (assuming you are OK with including empty/null rows in this count).
The max row length j, however, would require iterating over all the rows to find the row i having the maximum arr[i].length.
There will always be a loop1, even though the looping will be implicit in solutions that use Java 8 streams.
The complexity of getting the max number of columns is O(N) where N is the number of rows.
Implicit looping using streams probably will be less efficient than explicit looping using for.
Here's a neat solution using a for loop
int max = o;
for (int i = 0; i < array.length; i++) {
max = Math.max(max, array[i].length);
}
This works in the edge-case where array.length == 0, but if array or any array[i] is null you will get a NullPointerException. (You could modify the code to allow for that, but if the nulls are not expected, an NPE is probably a better outcome.)
1 - In theory, you could unroll the loops for all cases of array.length from 0 to Integer.MAX_VALUE, you would not need a loop. However, the code would not compile on any known Java compiler because it would exceed JVM limits on bytecode segments, etcetera. And the performance would be terrible for various reasons.
You could try this way: loop on the array and find the max length of the arrays which is in this array
byte[][] arrs = new byte[3][];
int maxLength = 0;
for (byte[] array : arrs) {
if (maxLength < array.length) {
maxLength = array.length;
}
}

Unexpected array index out of bounds exception

On the line with the "here" comment I get an index out of bounds error for some input data. It does not always occur. It does not occur when the program is run on my machine, even. It occurs when a project teammate runs the project on his laptop.
I know there's output from the exception regarding the actual index, but for reasons I don't have that information right now. I might be able to update with the full exception soon.
public int getDistance(int[] arrayA, int[] arrayB) {
int[][] array = new int[arrayA.length][arrayB.length];
for (int i = 0; i < arrayA.length; i++)
array[i][0] = i;
for (int i = 0; i < arrayB.length; i++)
array[0][i] = i; // Here
I cut the method off here as the remainder shouldn't be relevant.
As you can see I create a two dimensional array from two single dimensional arrays (arrayA and arrayB) and the width and height of that array equals the length of the two single dimensional arrays. Then I set the "leftmost" column to incrementing numbers and the "uppermost" row to incrementing numnbers.
If you need more code, I can post it.
When at least one of the array's lenght is 0 then it throws ArrayIndexOutOfBoundsException. Try for example:
int[] arrayA = new int[4];
int[] arrayB = new int[0];
getDistance(arrayA, arrayB);
my guess is that the exception occurs when one of the lists is of length 0, ie. lets say arrayA is the problem and has length=0, you then create array [0][arrayB.length] and when you then try to call array[0][i] it cant access element 0 and throws an OutofBoundsException

I get ArrayIndexOutofBoundsException - reverse the array

I get the output for the program mentioned below. In addition Ii also encounter an exception as:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 7
at ReverseOrder.main(ReverseOrder.java:15)
Why does this happen?
public class ReverseOrder {
public static void main(String[] args)
{
int anArray[]={1,2,3,4,5,6};
int anotherArray[]=new int[6];
for(int i=5,j=0;i>=0;i--,j++)
{
anotherArray[j]=anArray[i];
}
//System.out.println(anotherArray.length);
//System.out.println(anotherArray[2]);
for(int j=0;j<=anotherArray.length;j++)
{
System.out.println(anotherArray[j]);
}
}
}
Change
for(int j=0;j<=anotherArray.length;j++)
to
for(int j=0;j<anotherArray.length;j++)
Since if it's <= you'll be going out of bounds.
In Java (and most languages), arrays are zero-based. If you have an array of size N then its indexes will be from 0 to N - 1 (total size of N).
The problem is here:
for(int j=0;j<=anotherArray.length;j++)
{
System.out.println(anotherArray[j]);
}
you are accessing a position out of the array. This happen because method length gives you the number of elements in the array, and since the first position of an array is 0 and not 1 you should end the loop on anotherArray.length - 1 and not anotherArray.length.
There are two possible solutions to this where you modify your loop to:
a) for(int j=0;j<=anotherArray.length - 1;j++)or
b)for(int j=0;j<anotherArray.length;j++)
The latter (b) is preferable, since it has less arithmetic operations on it.
change
<=anotherArray.length
to
< anotherArray.length
For example, if array is
int arr[] = new int[2];
arr.length; // it will be 2, which is [0] and [1] so you can't go upto <=length,
// that way you will access [2] which is invalid and so the exception
for(int j=0;j<anotherArray.length;j++)
instead of
for(int j=0;j<=anotherArray.length;j++)
Because arrays are zero-based in Java.
You will get ArrayIndexOutOfBoundsException when you try access the element that's out of Array limit.
for(int j=0;j<anotherArray.length;j++) {
System.out.println(anotherArray[j]);
}
Why do you use this way to reverse your array in first place. Any way
for(int j=0;j<=anotherArray.length;j++) should change to
for(int j=0;j<anotherArray.length;j++)
Consider this too, It is easy.
int anArray[]={1,2,3,4,5,6};
int temp=0;
for (int i=0;i<anArray.length/2;i++){
temp=anArray[i];
anArray[i]=anArray[anArray.length-(1+i)];
anArray[anArray.length-(1+i)]=temp;
}
Now your array is reversed.

Categories