Java Exception : java.lang.ArrayIndexOutOfBoundsException - java

So for my Ap computer Science class One of my project keep getting java.lang.ArrayIndexOutOfBoundsException: 390000 Its a Sound reverse file
Here is the code:
import sounds.APSoundClip;
import sounds.Sample;
public class ReverseSound {
public static void main(String[] args) {
APSoundClip clip = new APSoundClip("money.wav");
APSoundClip newClip = clip.clone();
int pos = clip.getLength();
int cloned = 0;
for(Sample clipSample : clip) {
clip.getSample(pos); //error is here
int newValue = clipSample.getValue();
newClip.getSample(cloned).setValue(newValue);
pos--;
cloned++;
}
newClip.draw();
}
}

That seems like a "traditional" mistake - you initialize pos with int pos = clip.getLength();
Then at the first iteration you do clip.getSample(pos); - the last element is at index clip.getLength() - 1. You are trying to access the element at position clip.getLength(), that's why you are getting the index out of bounds error.

Java Arrays start with an index of zero, and because of this, their last index will be one less than their length. In your situation, you are assuming that clip.getLength()is the last element in the array, however, when you take a look at the anatomy of the array, it would really be clip.getLength()-1.

Related

All possible distinct subsets of characters in a given string JAVA

As title says I need to do the following. But I somehow am getting the wrong answer, perhaps something with the loops is wrong?
And here's what I have coded so far, but it seems to be giving me the wrong results. Any ideas, help, tips, fixes?
import java.util.ArrayList;
public class pro1
{
private String lettersLeft;
private ArrayList<String> subsets;
public pro1(String input)
{
lettersLeft = input;
subsets = new ArrayList<String>();
}
public void createSubsets()
{
if(lettersLeft.length() == 1)
{
subsets.add(lettersLeft);
}
else
{
String removed = lettersLeft.substring(0,1);
lettersLeft = lettersLeft.substring(1);
createSubsets();
for (int i = 0; i <= lettersLeft.length(); i++)
{
String temp = removed + subsets.get(i);
subsets.add(temp);
}
subsets.add(removed);
}
}
public void showSubsets()
{
System.out.print(subsets);
}
}
My test class is here:
public class pro1
{
public static void main(String[] args)
{
pro1s = new pro1("abba");
s.createSubsets();
s.showSubsets();
}
}
Try
int numSubsets = (int)java.lang.Math.pow(2,toSubset.length());
for (int i=1;i<numSubsets;i++) {
String subset = "";
for (int j=0;j<toSubset.length();j++) {
if ((i&(1<<j))>0) {
subset = subset+toSubset.substring(j,j+1);
}
}
if (!subsets.contains(subset)) {
subsets.add(subset);
}
}
where toSubset is the string that you wish to subset (String toSubset="abba" in your example) and subsets is the ArrayList to contain the results.
To do this we actually iterate over the power set (the set of all subsets), which has size 2^A where A is the size of the original set (in this case the length of your string).
Each subset can be uniquely identified with a number from 0 to 2^A-1 where the value of the jth bit (0 indexed) indicates if that element is present or not with a 1 indicating presence and 0 indicating absence. Note that the number 0 represents the binary string 00...0 which corresponds to the empty set. Thus we start counting at 1 (your example did not show the empty set as a desired subset).
For each value we build a subset string by looking at each bit position and determining if it is a 1 or 0 using bitwise arithmetic. 1<<j is the integer with a 1 in the jth binary place and i&(i<<j) is the integer with 1's only in the places both integers have a 1 (thus is either 0 or 1 based on if i has a 1 in the jth binary digit). If i has a 1 in the jth binary digit, we append the jth element of the string.
Finally, as you asked for unique subsets, we check if we have already used that subset, if not, we add it to the ArrayList.
It is easy to get your head all turned around when working with recursion. Generally, I suspect your problem is that one of the strings you are storing on the way down the recursion rabbit hole for use on the way back up is a class member variable and that your recursive method is a method of that same class. Try making lettersLeft a local variable in the createSubsets() method. Something like:
public class Problem1
{
private String originalInput;
private ArrayList<String> subsets;
public Problem1(String input)
{
originalInput = input;
subsets = new ArrayList<String>();
}
// This is overloading, not recursion.
public void createSubsets()
{
createSubsets(originalInput);
}
public void createSubsets(String in)
{
if(in.length() == 1)
{
// this is the stopping condition, the bottom of the rabbit hole
subsets.add(in);
}
else
{
String removed = in.substring(0,1);
String lettersLeft = in.substring(1);
// this is the recursive call, and you know the input is getting
// smaller and smaller heading toward the stopping condition
createSubsets(lettersLeft);
// this is the "actual work" which doesn't get performed
// until after the above recursive call returns
for (int i = 0; i <= lettersLeft.length(); i++)
{
// possible "index out of bounds" here if subsets is
// smaller than lettersLeft
String temp = removed + subsets.get(i);
subsets.add(temp);
}
subsets.add(removed);
}
}
Something to remember when you are walking through your code trying to think through how it will run... You have structured your recursive method such that the execution pointer goes all the way down the recursion rabbit hole before doing any "real work", just pulling letters off of the input and pushing them onto the stack. All the "real work" is being done coming back out of the rabbit hole while letters are popping off of the stack. Therefore, the first 'a' in your subsets list is actually the last 'a' in your input string 'abba'. I.E. The first letter that is added to your subsets list is because lettersLeft.length() == 1. (in.length() == 1 in my example). Also, the debugger is your friend. Step-debugging is a great way to validate that your code is actually doing what you expect it to be doing at every step along the way.

counting elements in an array imported from a data file

I am writing a program that will import values from a txt file in to an array, I then need to count how many of those elements are greater than or equal to 36. The data imports fine, and the total amount of values it displays is correct, but I can not get it display the amount of times the number 36 is found in the file. Thanks for any help!
public static void main(String[] args) throws Exception {
int[] enrollments = new int [100];
int count;
int FullClass;
double ClassPercentage;
return count (number of data items)
count = CreateArray(enrollments);
System.out.println (count );
FullClass = AddValues (enrollments);
System.out.println (FullClass)
ClassPercentage= FullClass/count;
System.out.print(ClassPercentage +"% of classes are full");
}//end main
/**
*
* #param classSizes
*/
public static int CreateArray(int[] classSizes) throws Exception{
int count = 0;
File enrollments = new File("enrollments.txt");
Scanner infile = new Scanner (enrollments);
while (infile.hasNextInt()){
classSizes[count] = infile.nextInt();
count++}//end while
return count; //number of items in an array
} // end CreateArray
/**************************************************************************/
/**
*
* #throws java.lang.Exception
*/
public static int AddValues (int[] enrollments) throws Exception{
{
int number = 0;
int countOf36s = 0;
while (infile.hasNextInt()) {
number = infile.next();
classSizes[count] = number;
if(number>=36) {
countOf36s++;
}
count++;
}
return countOf36s;
}// end AddValues
}//end main
Try this code to count the numbers that are greater than or equal to 36 while you are reading the file only. Change the code in your createArray method or write the below logic where ever you want to.
I tried executing this program. It works as expected. See below code
import java.util.*;
import java.io.*;
public class Test { //Name this to your actual class name
public static void main(String[] args) throws Exception {
int[] enrollments = new int [100]; //assuming not more than 100 numbers in the text file
int count; //count of all the numbers in text file
int FullClass; //count of numbers whose value is >=36
double ClassPercentage;
count = CreateArray(enrollments);
System.out.println (count);
FullClass = AddValues (enrollments);
System.out.println (FullClass);
ClassPercentage= FullClass/count;
System.out.print(ClassPercentage +"% of classes are full");
}
//Method to read all the numbers from the text file and store them in the array
public static int CreateArray(int[] classSizes) throws Exception {
int count = 0;
File enrollments = new File("enrollments.txt"); //path should be correct or else you get an exception.
Scanner infile = new Scanner (enrollments);
while (infile.hasNextInt()) {
classSizes[count] = infile.nextInt();
count++;
}
return count; //number of items in an array
}
//Method to read numbers from the array and store the count of numbers >=36
public static int AddValues (int[] enrollments) throws Exception{
int number = 0;
int countOf36s = 0;
for(int i=0; i<enrollments.length; i++) {
number = enrollments[i];
if(number>=36) {
countOf36s++;
}
}
return countOf36s;
}
}
Your code indicates that you might have misunderstood a couple of concepts and stylistic things. As you say in your comments you are new at this and would like some guidance as well as the answer to the question - here it is:
Style
Method names and variable names are by convention written starting with a lower case letter and then in camel case. This is in contrast to classes that are named starting with an upper case letter and camel case. Sticking to these conventions make code easier to read and maintain. A full list of conventions is published - this comment particularly refers to naming conventions.
Similarly, by convention, closing braces are put on a separate line when they close loops or if-else blocks.
throws Exception is very general - it's usual to limit as much as possible what Exceptions your code actually throws - in your case throws FileNotFoundException should be sufficient as this is what Scanner or File can throw at runtime. This specificity can be useful to any code that uses any of your code in the future.
Substance
You are creating the array up front with 100 members. You then call CreateArray which reads from a file while that file has more integers in it. Your code does not know how many that is - let's call it N. If N <= 100 (there are 100 integers or less), that's fine and your array will be populated from 0 to N-1. This approach is prone to confusion, though - the length of your array will be 100 no matter how many values it has read from the file - so you have to keep track of the count returned by CreateArray.
If N > 100 you have trouble - the file reading code will keep going, trying to add numbers to the array beyond its maximum index and you will get a runtime error (index out of bounds)
A better approach might be to have CreateArray return an ArrayList, which can have dynamic length and you can check how many there are using ArrayList.size()
Your original version of AddValues called CreateArray a second time, even though you pass in the array which already contains the values read from file. This is inefficient as it does all the file I/O again. Not a problem with this small example, but you should avoid duplication in general.
The main problem. As per prudhvi you are checking the number of integers in the file against 36, not each value. You can rectify this as suggested in that answer.
You do ClassPercentage= FullClass/count; Although ClassPercentage is a double, somewhat counter intuitively - because both the variables on the Right Hand Side (RHS) are int, you will have an int returned from the division which will always round down to zero. To make this work properly - you have to change (cast) one of the variables on the RHS to double before division e.g. ClassPercentage= ((double)FullClass)/count;.
If you do keep using arrays rather than ArrayList, be careful what happens when you pass them into methods. You are passing by reference, which means that if you change an element of an array in your method, it remains changed when you return from that method.
In your new version you do
...
classSizes[count] = number;
if(number>=36) {
...
You almost certainly mean
...
number = classSizes[count];
if(number>=36) {
...
which is to say in programing the order of the assignment equals is important, so a = b is not equivalent to b = a
Code
A cleaned up version of your code - observing all the above (I hope):
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class ClassCounter
{
public static void main(String[] args) throws FileNotFoundException
{
int count;
int fullClass;
double classPercentage;
ArrayList<Integer> enrollments = createArray();
count = enrollments.size();
System.out.println(count);
fullClass = addValues(enrollments);
System.out.println(fullClass);
classPercentage = fullClass / count;
System.out.print(classPercentage + "% of classes are full");
}
/**
* scans file "enrollments.txt", which must contain a list of integers, and
* returns an ArrayList populated with those integers.
*
* #throws FileNotFoundException
*/
public static ArrayList<Integer> createArray() throws FileNotFoundException
{
ArrayList<Integer> listToReturn = new ArrayList<Integer>();
File enrollments = new File("enrollments.txt");
Scanner infile = new Scanner(enrollments);
while (infile.hasNextInt())
{
listToReturn.add(infile.nextInt());
}
return listToReturn;
}
/**
* returns the number of cases where enrollments >= 36 from the list of
* all enrollments
*
* #param enrollments - the list of enrollments in each class
* #throws FileNotFoundException
*/
public static int addValues(ArrayList<Integer> enrollments)
{
int number = 0;
int countOf36s = 0;
int i = 0;
while (i < enrollments.size())
{
number = enrollments.get(i);
if (number >= 36)
{
countOf36s++;
}
}
return countOf36s;
}
}

Nullpointer exception java runtime [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
The program looks slightly advanced; it is not. Simple manipulation of array.
The program compiles correctly, however, it encounters an exception run-time.
Exception in thread "main" java.lang.NullPointerException
at Ordliste.leggTilOrd(Tekstanalyse.java:85)
at Tekstanalyse.main(Tekstanalyse.java:23)
So there is something wrong with if(s.equalsIgnoreCase(ordArray[k])).
I cannot see why. It even provides the correct output.
import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;
public class Tekstanalyse {
public static void main(String[] args) throws FileNotFoundException {
Ordliste ol = new Ordliste();
ol.lesBok("scarlet.text");
ol.leggTilOrd("A");
}
}
class Ordliste {
private int i = 0;
private String[] ordArray = new String[100000];
private int antForekomster;
private int arrStorrelse = 0;
public void lesBok(String filnavn) throws FileNotFoundException {
File minFil = new File(filnavn);
Scanner scan = new Scanner(minFil);
while (scan.hasNextLine()) {
ordArray[i] = scan.nextLine();
//System.out.println(ordArray[i]);
i++;
arrStorrelse++;
}
System.out.println("Array size: " + arrStorrelse + " Capacity: " + ordArray.length);
}
public void leggTilOrd(String s) {
for (int k = 0; k < ordArray.length; k++) {
if (s.equalsIgnoreCase(ordArray[k])) {
antForekomster++;
System.out.println("Den har vi sett for!");
} else {
s = ordArray[arrStorrelse];
}
}
}
}
I'm pretty sure the error is right here:
for (int k = 0; k < ordArray.length; k++) {
if (s.equalsIgnoreCase(ordArray[k])) {
antForekomster++;
System.out.println("Den har vi sett for!");
} else {
s = ordArray[arrStorrelse]; // <- dangerous
}
}
As I said in the comment, ordArray could contain null elements if the read text file does not contain 100.000 lines of text. If this is the case, the above line would write null to s because s.equalsIgnoreCase(null) is false.
You should think about using a list instead of an array.
private List<String> ordList = new ArrayList<String>();
(or use a different variable name, it is up to you)
Then you can add new entries to the list using ordList.add(scan.nextLine());. This list won't contain any null elements and your mentioned problem should be gone.
I would highly recommend you to simply use a debugger to debug your code , but here goes:
in your lesBok method you fill your array with strings and make a counter arrStorrelse. to be the amount of elements in the array you made. however the array is filled for indexes 0 to n-1. and arrStorrelse is equal to N you did however allocate space in the array for this. so when in leggTilOrd() you iterate the first time and you enter the else clause you do this
for (int k = 0; k < ordArray.length; k++) {
if (s.equalsIgnoreCase(ordArray[k])) {
antForekomster++;
System.out.println("Den har vi sett for!");
}
else {
int arrStorrelse2=arrStorrelse;
s = ordArray[arrStorrelse];
}
in that else clause s is set to ordArray[arrStorrElse]; however arrStorrElse is at that moment one higher than the last intialised element of your array. so it sets s to the null pointer.
then the next iteration of your loop in the if clause
if (s.equalsIgnoreCase(ordArray[k])) {
antForekomster++;
System.out.println("Den har vi sett for!");
the s.equalsIgnoreCase() call is done on an s that is null that's where the null pointer exception comes from.
you need to change the arrStorrElse assignment you haven't explained what it should do so i can't do that for you also try to learn how to debug your code here is a usefull link:
http://www.tutorialspoint.com/eclipse/eclipse_debugging_program.htm
I have compiled and tested your code.
s.equalsIgnoreCase(null)
throws nullPointerException.
Maybe you should try to use ArrayList instead of Array to avoid iterating through nulls.
It took me some time to figure out why the NullPointerException occurs and I have to agree with Piotr and Tom: The NPE is caused by the line
s.equalsIgnoreCase(ordArray[k])
and a side-effect in your code. This side-effect is introduced by reassigning the parameter s in the else-branch to null (this value comes from ordArray[arrStorrelse]). After this reassignment happened, you will have something like this:
null.equalsIgnoreCase(ordArray[k])
And voila, there is the NullPointerException.

What causes the ArrayIndexOutOfBoundsException?

This is a question in the book "Cracking the Coding Interview". Here is Java code, but why does it cause the ArrayIndexOutOfBoundsException? I just copied from the book.
class Q1_3{
public static void removeDuplicates(char[] str){
if(str==null) return;
int len=str.length;
if(len<2) return;
int t=1;
for(int i=1;i<len;++i){
int j;
for(j=0;j<t;++j){
if(str[i]==str[j])
break;
}
if(j==t){
str[t]=str[i];
++t;
}
}
str[t]=0; //why ?
}
public static void main(String[] args){
char ss1[] = {'a','b','c','d'};
char ss2[] = {'a','a','a','a'};
char ss3[] = {};
char ss4[] = {'a','a','b','b'};
removeDuplicates(ss1);
removeDuplicates(ss2);
removeDuplicates(ss3);
removeDuplicates(ss4);
System.out.println(ss1);
System.out.println(ss2);
System.out.println(ss3);
System.out.println(ss4);
}
}
It's really weird code, the naming and the use of control structures its... questionable...
The code breaks when there is no duplicated chars, t increases his value in all iterations and at the end is 4, this is what causes de exception.
in the example the code only crash with ss1, and "works" with the others.
If you debug the code closely, you will find that after comparing the value for the last element in the inner for loop you increment the value of t, thus the value of t will be str.length. But, array index start from 0 till str.length-1. So eventually, when you try to insert value at index str.length you will get the exception.

Exception in thread ArrayIndex

I was doing some beginner programming with series and input but im having the same problem constantly.Cant find the solution.Basically what i want my program to do for now i input a list of numbers and print them out.And im getting the same error over and over whatever i change in program.Here is my code.
import java.util.Scanner;
public class Test437 {
public static void main(String[] args) {
int limit = 25;
int cnt;
int addtion;
double dbt; //Devided by two % 2
Scanner input = new Scanner(System.in);
int [] ya = new int[8];
for(cnt = 0;cnt < ya.length;cnt++)
{
System.out.print("ya[" + cnt + "]= ");
ya[cnt] = input.nextInt();
}
System.out.println(ya[cnt]);
}
}
Im getting this error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 8
at Test437.main(Test437.java:22)
System.out.println(ya[cnt]); this line is outside loop. Cnt is equal to an array size so it cannot be used in such way because there is no element in the array with such index.
The line:
System.out.println(ya[cnt]);
needs to be in a loop again to print out all the array values after accepting them:
for (cnt = 0;cnt < ya.length;cnt++) {
System.out.println(ya[cnt]);
}
Alternatively, you could do:
System.out.println(Arrays.toString(ya));
cnt condition to leave the loop is to exceed the length therefore you get in indexoutofbounds
This line
System.out.println(ya[cnt]);
is trying to access element at ya.Length index which does not exists.
In your example ya[8] contains elements at position from 0 to 7 (ya[0] ya[1] ... ya[7] and you're trying to access ya[8] bacuase cnt variable is 8 after the for statement ends.
Therefore the compiler throws an indexOutOfBounds exception.

Categories

Resources