This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 3 years ago.
The homework requires reading two file and entering the information of students into two separate ArrayLists. Then I need to perform 2 functions: combine the two lists and sort the combined list.
public abstract class Tools {
public static ArrayList<JUPASStudent> readJUPASFile(String f) throws Exception {
ArrayList<JUPASStudent> jList = new ArrayList<JUPASStudent>();
BufferedReader readbuffer = null;
readbuffer = new BufferedReader(new FileReader(f));
String strRead;
while ((strRead = readbuffer.readLine()) != null) {
String splitarray[] = strRead.split("/t");
String firstentry = splitarray[0];
String secondentry = splitarray[1];
JUPASStudent x = new JUPASStudent(firstentry, Double.parseDouble(secondentry));
jList.add(x);
}
readbuffer.close();
return jList;
}
public static ArrayList<NonJUPASStudent> readNonJUPASFile(String f) throws Exception {
ArrayList<NonJUPASStudent> njList = new ArrayList<NonJUPASStudent>();
BufferedReader readbuffer = null;
readbuffer = new BufferedReader(new FileReader(f));
String strRead;
while ((strRead = readbuffer.readLine()) != null) {
String splitarray[] = strRead.split("/t");
String firstentry = splitarray[0];
String secondentry = splitarray[1];
NonJUPASStudent x = new NonJUPASStudent(firstentry, Double.parseDouble(secondentry));
njList.add(x);
}
readbuffer.close();
return njList;
}
public static ArrayList<Student> combineArrayList(ArrayList<JUPASStudent> S1, ArrayList<NonJUPASStudent> S2) {
ArrayList<Student> sList = new ArrayList<Student>();
for (int i = 0; i < S1.size(); i++)
sList.add(S1.get(i));
for (int i = 0; i < S2.size(); i++)
sList.add(S2.get(i));
return sList;
}
public static ArrayList<Student> sort(ArrayList<Student> s){
for (int i = 0; i < s.size()-1; i++) {
for (int j = 0; i < s.size()-i-1; j++) {
if (s.get(j).getResult() > s.get(j+1).getResult()) {
Student Temp = s.get(j);
s.set(j, s.get(j+1));
s.set(j+1, Temp);
}
}
}
return s;
}
}
However, I keep getting "Index 1 out of bounds for length 1"
In the inner loop you're defining a constraint to the wrong counter. Instead of :
for (int j = 0; i < s.size()-i-1; j++)
there should be:
for (int j = 0; j < s.size()-i-1; j++)
In package java.util, we can :
Collections.sort(List); // to sort list, ex:
Collections.sort(Arrays.asList(13, 4));
Collections.addAll(Collection c, T... elements); // to join list, ex :
Collections.addAll(Arrays.asList(13, 4), Arrays.asList(3,4,5));
So you don't need to write your own function anymore.
The issue you are facing might be in the below line.
in method readNonJUPASFile and readJUPASFile
String secondentry = splitarray[1];
You are splitting the String based on /t. If you are expecting to split it based on tab you should be giving \t. If your line does not contain /t as you have given you will probably get a ArrayIndexOutOfBoundsException. You should check the length before assigning the variable like
if (splitarray.length > 1) {
String firstentry = splitarray[0];
String secondentry = splitarray[1];
}
Can you add few system.out statements. It will help you see where the error. I suspect data from file.
Related
Here is my class below, that compares elements in two string arrays, and returns the word with the highest frequency in both arrays. However as visible from the output, the first index is appending none to null in spite of initializing both arrays with the String none. Can someone kindly let me know what I am doing wrong that is leading to this?
public class HelloWorld{
public String[] pro;
public String[] con;
String proSplitter;
String conSplitter;
public HelloWorld() {
this.pro = new String[9];
this.con = new String[9];
for(int i=0;i<this.pro.length;i++)
{
this.pro[i]="none";
this.con[i]="none";
}
}
public String[] getPro() {
return pro;
}
public String[] getCon() {
return con;
}
public void setPro(String pros, int proIndex) {
pro[proIndex] = pros;
}
public void setCon(String cons, int conIndex) {
con[conIndex] = cons;
}
public String[] proWord(){
for(int i=0;i<9;i++)
{
proSplitter = proSplitter + pro[i] + ",";
}
for(int i=0;i<9;i++)
{
conSplitter = conSplitter + con[i] + ",";
}
String[] values = proSplitter.split(",");
for(int i=0;i<values.length;i++)
{
values[i] = values[i].trim();
}
String[] values1 = conSplitter.split(",");
for(int i=0;i<values1.length;i++)
{
values1[i] = values1[i].trim();
}
int [] fr = new int [values.length];
int visited = -1;
for(int i = 0; i < values.length; i++){
int count = 1;
for(int j = i+1; j < values.length; j++){
if(!values[i].equalsIgnoreCase("none"))
{
if(values[i].compareTo(values[j])==0){
count++;
//To avoid counting same element again
fr[j] = visited;
}
}
}
if(fr[i] != visited)
fr[i] = count;
}
int max = fr[0];
int index = 0;
for (int i = 0; i < fr.length; i++)
{
if (max < fr[i])
{
max = fr[i];
index = i;
}
}
int [] fr1 = new int [values1.length];
int visited1 = -1;
for(int i = 0; i < values1.length; i++){
int count1 = 1;
for(int j = i+1; j < values1.length; j++){
if(!values1[i].equalsIgnoreCase("none"))
{
if(values1[i].compareTo(values1[j])==0){
count1++;
//To avoid counting same element again
fr1[j] = visited1;
}
}
}
if(fr1[i] != visited1)
fr1[i] = count1;
}
for(int i = 0;i<values.length;i++)
{
System.out.println("pro = "+values[i]);
}
for(int i = 0;i<values1.length;i++)
{
System.out.println("con = "+values1[i]);
}
int max1 = fr1[0];
int index1 = 0;
for (int i = 0; i < fr1.length; i++)
{
if (max1 < fr1[i])
{
max1 = fr1[i];
index1 = i;
}
}
String sentence[] = new String[2];
if(values[index].equalsIgnoreCase(values1[index1])) {
sentence[0] = "balanced";
}else {
sentence[0] = values[index];
sentence[1] = values1[index1];
}
return sentence;
}
public static void main(String[] args){
HelloWorld tracker = new HelloWorld();
tracker.setPro("Apple, Pear", 1);
tracker.setCon("Banana", 1);
tracker.setPro("Apple", 2);
tracker.setCon("Water Melon", 2);
tracker.setPro("Guava", 3);
tracker.setCon("Ball", 3);
tracker.setPro("Apple", 4);
tracker.setCon("Mango, Plum", 4);
String[] arr = tracker.proWord();
System.out.println("pro = "+arr[0]);
System.out.println("con = "+arr[1]);
}
}
The output being generated is :
pro = nullnone
pro = Apple
pro = Pear
pro = Apple
pro = Guava
pro = Apple
pro = none
pro = none
pro = none
pro = none
con = nullnone
con = Banana
con = Water Melon
con = Ball
con = Mango
con = Plum
con = none
con = none
con = none
con = none
pro = Apple
con = nullnone
As mentioned by Arnaud, the immediate problem is that you're leaving proSplitter uninitialized, so its value is null. Then, when you come to append a string to it with proSplitter = proSplitter + pro[i] + ",";, proSplitter will be converted (effectively) to "null", and then stuff is appended to the end. So, instead, make it "" initially.
However, you've got another problem here, which is that you're mutating a member variable each time you invoke that method - so it's not null (or empty) second time around, it still contains what was there previously.
The fix for that is straightforward: instead of using a member variable, declare these as local variables.
You've also got the problem that you're effectively duplicating the code to count the most frequent thing in an array: this is what methods are for, to allow you to run the same code over different inputs.
You can also make use of library methods. For example:
String mostFrequent(String[] array) {
int maxFreq = 0;
String maxFreqS = "";
for (String s : array) {
if (s.equalsIgnoreCase("none")) continue;
int freq = Collections.frequency(Arrays.asList(array), s);
if (freq > maxFreq) {
maxFreq = freq;
maxFreqS = s;
}
}
return maxFreqS;
}
(There are lots of inefficiencies here. The point is more about writing this as a method, to remove the duplication).
Then you can use this inside your existing method, and it will be a whole lot easier for others - and you - to read.
I am opening a text file that looks like this:
1;Rani;Hockey;BMW;1 Series;2011;WAUGFAFR4CA952133;2003;
2;Ranice;Dodge;Hyundai;Sonata;2005;WAUMF78PX6A683500;2013;
(has 90 more lines similar to the above)
I have already split each words into a 2D array such that positions
[0][0] = 1
[0][1] = Rani
[0][2] = Hockey
[1][0] = 2
[1][1] = Ranice
[1][7] = 2013
I setup a for-loop to iterate through my 2D Array where (eventually) each index will be passed as a parameter to a constructor that I have. During the loop I keep getting:
Exception in thread "main" java.lang.NumberFormatException:
For input string: "2"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at Test4.main(Test4.java:53)
Below are my code for my CarData class:
public CarData() {}
public CarData(int i, String fn, String ln, String cMake, String cMdl,
int cYear, String vin, int p)
{
this.customerID = i;
this.ownerFirstName = fn;
this.ownerLastName = ln;
this.carMake = cMake;
this.carModel = cMdl;
this.carYear = cYear;
this.carVin = vin;
this.yearCarPurchased = p;
}
public class CarDataDriver {
public static void main(String [] args)
{
final int col = 8;
final int row = 100;
int id = 0;
String fn = null;
String ln = null;
String cMake = null;
String cMdl = null;
int cYear = 0;
String vin = null;
int p = 0;
CarData [] data = new CarData[row];
// Open file
File file = new File("CarData.txt");
// Use scanner to scan new File
Scanner scanner;
try {
scanner = new Scanner(file);
// useDelimiter to separate String
String text = scanner.useDelimiter("\\A").next();
// Use split method to split String
String [] array = text.split(";");
String[][] array2D = new String[row][col];
//iterate through array to create 2D array
for (int i = 0, k=0; i < array2D.length; i++)
{
for (int j = 0; j < col; j++)
{
array2D[i][j] = array[k++];
}
}
for (int i = 0, k=0; i < array2D.length; i++)
{
for (int j = 0; j < col; j++)
{
if(j==0){
id = Integer.parseInt(array2D[i][j]); //first iteration where i = 0 runs fine, when i=1 and j=0 I get the error
continue;
}
if(j==1){
fn = array2D[i][j];
continue;
}
if(j==2) {
ln = array2D[i][j];
continue;
}
if(j==3){
cMake = array2D[i][j];
continue;
}
if(j==4){
cMdl = array2D[i][j];
continue;
}
if(j==5){
cYear = Integer.parseInt(array2D[i][j]);
continue;
}
if(j==6){
vin = array2D[i][j];
continue;
}
if(j==7){
p = Integer.parseInt(array2D[i][j]);
}
data[k] = new CarData(id, fn, ln, cMake, cMdl, cYear, vin, p);
k++;
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
Your looping alone is fine - what is causing an error is an invalid character (a whitespace) parsed together with proper integer. You may simply remove all whitespaces from your string with:
array2D[i][j].replaceAll("\\s+","")
(note, that this not modifies a string in array, but returns new one with removed spaces)
Where strange "\\s+" string just means "any space character" (it's so called regular expression, but you don't need to understand it fully for now)
However, note, that you have some more issues in your code, for example absolutely unnecessary inner loop with so numerous ifs, where every of them would execute just once - instead of this you can simply access array2D[i][1], array2D[i][2] and so on. Also keeping additional index k and incrementing it by hand seems to be redundant.
Anyway, keep coding and good luck!
P.S. Using BufferedReader and its readLine() seems to be a much better (and simpler!) way to read a file. Take a glimpse on https://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html
I'm practice to write java code and i try to fix this but i don't know how to fix it anymore. I'll show you my code.
In my Fortunecookie.java is:
public class FortuneCookie {
private String subjectList;
private String objectList;
private String verbList;
private int sWord;
private int oWord;
private int vWord;
private Random random = new Random() enter code here;
public FortuneCookie() {
subjectList = "I#You#He#She#It#They";
objectList = "me#you#him#her#it#";
verbList = "hate#love#deny#find#hear#forgive#hunt#win#teach";
}
public String getFortuneMsg() {
StringTokenizer subSt = new StringTokenizer(subjectList,"#");
StringTokenizer objSt = new StringTokenizer(objectList,"#");
StringTokenizer verbSt = new StringTokenizer(verbList,"#");
sWord = subSt.countTokens();
oWord = objSt.countTokens();
vWord = verbSt.countTokens();
int c1 = random.nextInt(sWord);
String line1 = " ";
String line2 = " ";
String line3 = " ";
while(subSt.hasMoreTokens()) {
line1 = subSt.nextToken("#");
for (int i=0;i<sWord;i++)
if (i == c1) {
break;
}
else{
line1 = subSt.nextToken("#");
}
}
int c2 = random.nextInt(oWord);
while(objSt.hasMoreTokens()) {
line2 = objSt.nextToken("#");
for (int i=0;i<sWord;i++)
if (i == c2) {
break;
}
else{
line2 = objSt.nextToken("#");
}
}
int c3 = random.nextInt(vWord);
while(verbSt.hasMoreTokens()) {
line3 = verbSt.nextToken("#");
for (int i=0;i<sWord;i++)
if (i == c3) {
break;
}
else{
line3 = verbSt.nextToken("#");
}
}
return line1+line2+line3;
}
public void setSubjectList(String aSubjectList) {
subjectList = aSubjectList;
}
public void setObjectList(String aObjectList) {
objectList = aObjectList;
}
public void setVerbList(String aVerbList) {
verbList = aVerbList;
}
public void print() {
StringTokenizer subSt = new StringTokenizer(subjectList,"#");
StringTokenizer objSt = new StringTokenizer(objectList,"#");
StringTokenizer verbSt = new StringTokenizer(verbList,"#");
sWord = subSt.countTokens();
oWord = objSt.countTokens();
vWord = verbSt.countTokens();
System.out.println("Subject List : "+subjectList);
System.out.println("Object List : "+objectList);
System.out.println("Verb List : "+verbList);
}
And in my FortuneCookieTest.java is
public class FortuneCookieTest {
public static void main(String[] args) {
FortuneCookie ck = new FortuneCookie();
System.out.println(ck.getFortuneMsg());
}
}
And when I compile and run it:
//Exception in thread "main" java.util.NoSuchElementException
at java.util.StringTokenizer.nextToken(Unknown Source)
at java.util.StringTokenizer.nextToken(Unknown Source)
at CS_111_Homework_2.FortuneCookie.getFortuneMsg(FortuneCookie.java:39)
at CS_111_Homework_2.FortuneCookieTest.main(FortuneCookieTest.java:6)
How can I solve it?
In this part of the code, you can call objSt.nextToken("#") twice, and if the first calls gets the last element, on the second call you'll get the NoSuchElementException as no more elements are available.
while (objSt.hasMoreTokens()) {
line2 = objSt.nextToken("#");
for (int i = 0; i < sWord; i++)
if (i == c2) {
break;
} else {
line2 = objSt.nextToken("#");
}
}
This is a different use case, but has the same problem
Actually there are several issues with the code, specially with this method getFortuneMsg() :
you are using sWord for all the loops, instead you should use sWord for the first loop oWordfor the second and vWordand for the last.
Also you are calling line1 = subSt.nextToken("#"); before starting the loop so you have consumed one token already, this could produceNoSuchElementException i suggest to change this for (int i=0; i<sWord; i++) to this for (int i=0; i<sWord - 1; i++) to take in consideration the consumed token.
And for this loop while(subSt.hasMoreTokens()) it will be started all over again if not all tokens are consumed (it could be happen when c1 < sWord) .
Note: The code need some refactoring to prevent duplication and use loops wisely.
Edit: I didn't understand exactly what you are trying to achieve but if I were you I would like to change this method getFortuneMsg() to something like this:
public String getFortuneMsg() {
StringTokenizer[] tokenizers = {new StringTokenizer(subjectList, "#"), new StringTokenizer(objectList, "#"), new StringTokenizer(verbList, "#")};
StringBuilder sb = new StringBuilder();
for (StringTokenizer tokenizer : tokenizers) {
int rCount = random.nextInt(tokenizer.countTokens());
for (int i = 0; i < rCount; i++) {
tokenizer.nextToken();
}
sb.append(tokenizer.nextToken());
}
return sb.toString();
}
I want to read and save the content of the file in a 2d array, but I don't know the size of the file, because the program should read different files. So there is the first problem after "new char". I searched for the problem and found that "matrix[x][y]=zeile.charAt(x);"
should be right, but that throws the error "NullPointerException" when I write any number into the first brackets of new char.
Could somebody explain and give some ideas oder solutions? Thank you :)
import java.io.*;
class Unbenannt
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("Level4.txt");
BufferedReader br = new BufferedReader(fr);
String zeile = br.readLine();
char [][] matrix = new char [][];
while(zeile != null )
{
int y = 0;
for(int x = 0; x < zeile.length(); x++) {
matrix[x][y] = zeile.charAt(x);
}
y++;
} System.out.print(matrix);
br.close();
}
}
Arrays are stored as blocks in memory in order to achieve O(1) operations, which is why you need to define their size during definition. If you insist on arrays (rather than a dynamic ADT such as List), you'll need to know the dimensions in advance.
What you could do is store the file lines temporarily in a list and find out the maximum line length, i.e.:
List<String> lines = new ArrayList<String>();
String zeile = null;
int max = 0;
while ((zeile = br.readLine()) != null) {
lines.add(zeile);
if (zeile.length() > max)
max = zeile.length();
}
char[][] matrix = new char[lines.length()][max];
// populate the matrix:
for (int i = 0; i < lines.length(); i++) {
String line = lines.get(i);
for (int j = 0; j < line.length(); j++) {
matrix[i][j] = line.charAt(j);
}
}
Note that since char is a primitive, you'll be initialized with the default value 0 (the integer, not the character!) in every cell of the inner array, so for lines which are shorter than the others, you'll have trailing zero characters.
you initialize the matrix (char [][]) but you never initialize any of the inbound arrays. This leads to the NullPointerException.
In addition your 'while' condition looks invalid, seems you only are reading the first line of your file here > your code will never complete and read the first line over and over again
Thank you all! It works! But there is still one problem. I changed lines.length() into lines.size(), because it doesn't work with length. The problem is the output. It shows for example: xxxx xxxx instead of "xxx" and "x x" and "xxx" among each other.
How can I build in a line break?
my programcode is:
import java.io.*;
import java.util.ArrayList;
class Unbenannt
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("Level4.txt");
BufferedReader br = new BufferedReader(fr);
ArrayList<String> lines = new ArrayList<String>();
String zeile = null;
int max = 0;
while ((zeile = br.readLine()) != null) {
lines.add(zeile);
if (zeile.length() > max)
max = zeile.length();
}
char [][] matrix = new char[lines.size()][max];
for(int i = 0; i < lines.size(); i++) {
String line = lines.get(i);
for(int j = 0; j < line.length(); j++) {
matrix[i][j] = line.charAt(j);
System.out.print(matrix[i][j]);
}
}
br.close();
}
}
I try to convert a file to an array of integers, do not know where my mistake is that when I print the array empty array throws
I leave my method , thanks you
public int[] ConvertToArray(File xd) throws IOException {
String sCadena;int i=0;
int[]array;
FileReader fr = new FileReader(xd);
BufferedReader bf = new BufferedReader(fr);
int lNumeroLineas = 0;
while ((sCadena = bf.readLine())!=null) {
lNumeroLineas++;
}
array = new int[lNumeroLineas];
while ((sCadena = bf.readLine())!=null) {
lNumeroLineas++;
array[i]=Integer.parseInt(sCadena);
i++;
}
for (int j = 0; j < array.length; j++) {
System.out.println(array[i]);
}
return array;
}
You are already at the end of file after your first while loop completes.
So reading from BufferedReader object bf again after first while loop ends will always give you null(End of file) and second iteration will never run.
Also in the for loop you are printing array[i] however for loop is iterating over j variable
You can do it like this with help of ArrayList:
public int[] ConvertToArray(File xd) throws IOException {
String sCadena;
ArrayList<Integer> array = new ArrayList();
FileReader fr = new FileReader(xd);
BufferedReader bf = new BufferedReader(fr);
int lNumeroLineas = 0;
while ((sCadena = bf.readLine())!=null) {
lNumeroLineas++;
array.add(Integer.parseInt(sCadena.trim())); //always recomended to trim(); to remove trailing whitespaces.
}
for (int j = 0; j < array.size(); j++) {
System.out.println(array.get(j));
}
return covertIntegers(array);
}
Edited: If you want to send int[] instead of ArrayList<Integer> without using any external libraries.
public static int[] convertIntegers(List<Integer> integers)
{
int[] ret = new int[integers.size()];
for (int i=0; i < ret.length; i++)
{
ret[i] = integers.get(i).intValue();
}
return ret;
}
You are reading the file with two loops but open only once. Reopen the file reader before the second while and it will work.