ArrayIndexOutOfBounds when trying to add to list from string array - java

I am having one problem that is preventing my entire code from working. It is having an array index out of bounds error, but it matches the file array perfectly, so I'm not sure what the problem is..
public void Menu() {
prompt.welcomeMsg();
prompt.nGramOptionMsg();
String userInput = input.next();
while (userInput.charAt(0) != 's' || userInput.charAt(0) != 'S') {
if (userInput.charAt(0) == 'n' || userInput.charAt(0) == 'N') {
prompt.nGramLengthMsg();
int userIntut = input.nextInt();
nGram = new NGram(userIntut);
prompt.fileUpload();
String userFilePut = input.next();
FileOpener file = new FileOpener(userFilePut);
String[] fileArray = file.openFile();
for (int i = 0; i < fileArray.length; i++) {
String[] splitedFileArray = fileArray[i].split("\\s+");
list.add(splitedFileArray[i]);
}
String[] listToStringArray = (String[]) list.toArray(new String[0]);
String[] nGrams = nGram.arrayToNGram(fileArray);
for (int i = 0; i < nGrams.length; i++) {
Word word;
if (!hashMap.containsKey(nGrams[i])) {
word = new Word(nGrams[i], 1);
hashMap.put(word.getNGram(), word);
} else {
Word tempWord = hashMap.remove(nGrams[i]);
tempWord.increaseAbsoluteFrequency();
hashMap.put(tempWord.getNGram(), tempWord);
}
}
HashMapFiller fill = new HashMapFiller();
fill.hashMap(hashMap);
fill.print();
prompt.goAgain();
}
}
The problem occurs when the list.add is trying to add the splitedFileArray. I tried doing fileArray.length-1 but it had a similar error, except -1.

The root cause for this problem is that you are trying to access the array in following line. What actually happening in behind the scenes is that you actually try to access unknown sized array which is returned from the split() method. returned array size might be less than the defined index (in your case i).
list.add(splitedFileArray[i]);
You can resolve this problem as follows..
for (int i = 0; i < fileArray.length; i++) {
String[] splitedFileArray = fileArray[i].split("\\s+");
list.addAll(Arrays.asList(splitedFileArray));
}
Hope this answer will help you to resolve your problem...

Related

Compare arraylists for non identical elements

Hello there I am being confused in comparing two array lists, one of my array list is as:
private ArrayList<String> members = new ArrayList<>();
members.add("member123keyxyzmember123 number");
members.add("member456keyxyzmember456 number");
members.add("member789keyxyzmember789 number");
members.add("member2233keyxyzmember2233 number");
members.add("member1122keyxyzmember1122 number");
The second arraylist is as:
private ArrayList<String> syncMembers = new ArrayList<>();
syncMembers.add("member123keyxyz123statuskeyxyz123photokeyxyzmember123 number");
syncMembers.add("member456keyxyz456statuskeyxyz456photokeyxyzmember456 number");
The problem is that I am comparing both so that they give me the numbers that are in members list and are not in syncMembers list!
That is the out put should be:
member789 number
member2233 number
member1122 number
only!
What I have been trying is:
for (int i = 0; i < members.size(); i++) {
String stringFromMembersList = members.get(i);
String[] memberParts = stringFromMembersList.split("keyxyz");
String memberNumber = memberParts[1];
//Log.e("hgax", "sync:::" + memberNumber);
for (int j = 0; j < syncMembers.size(); j++) {
String stringFromSyncList = syncMembers.get(j);
String[] syncParts = stringFromSyncList.split("keyxyz");
String n = syncParts[3];
if (memberNumber.equals(n)) {
//Log.e("hgax", "hee:::" + n);
break;
} else {
Log.e("hgax", "ssshee:::" + memberNumber);
}
}
}
The output I am getting is:
member456 number
member789 number
member789 number
member2233 number
member2233 number
member2233 number
member1122 number
member1122 number
member1122 number
member1122 number
I am bit confuse what is happeing to me and What i have been doing wrong? Can somebody please tell what blunder I am doing Thanks in advance
Try to think about what you need to check to reach your goal. In order to determine that a member in the list members does not exist in syncMembers you have to check the entirety of the syncMembers list for that member. Since the lists are not identical (as your question states), you cannot use Collection.contains(Object o).
This should achieve your goal:
// We need this initial check as if syncMembers is empty it'll display all members
// And why bother to do this if syncMembers is empty anyway!
if (!syncMembers.isEmpty()) {
for (String member : members) {
String memberNo = member.split("keyxyz")[1];
int i = 0;
boolean found = false;
while (!found && i < syncMembers.size()) {
// Iterate over syncMembers until a match if found
// or we have exhausted the list
found = syncMembers.get(i).split("keyxyz")[3].equals(memberNo);
i++;
}
if (!found) {
// Display only if not found
System.out.println(memberNo);
}
}
}
Edit: updated answer to include the original mixed values in the arrayList
ArrayList<String> membersList = new ArrayList<>();
ArrayList<String> syncMembersList = new ArrayList<>();
for (int i = 0; i < members.size(); i++) {
String s = members.get(i).substring(members.get(i).lastIndexOf("member"));
membersList.add(s);
}
for (int j = 0; j < syncMembers.size(); j++) {
String s = syncMembers.get(j).substring(syncMembers.get(j).lastIndexOf("member"));
syncMembersList.add(s);
}
for (int i = 0; i < membersList.size(); i++) {
if (!syncMembersList.contains(membersList.get(i))) {
System.out.println(membersList.get(i));
}
}
This will print the output you require.

ArrayIndexOutOfBound when parsing int from string array

I am new to StackExchange so I will do my best at making this question as understable as possible. I am trying to take all Integers from a String Array created from a .csv file. The file looks like so,
type,name,untiprice,quantity
Bitem,toothpaste,1.50,2
Fitem,eggs,2.50,1
and so on...
Everything works perfectly until I try to add the numbers to the array. The output returns a ArrayIndexOutOfBoundsException. I made the MAX_SIZE of this array = 100. The amount of integers in the text file is no more than 8. I don't understand why this is problem is happening. Are my for-loops completely wrong or is there more to the problem?
public static void loadNums()
{
String inputFile=("/Users/user1/Desktop/list.csv");
File file = new File(inputFile);
Scanner scanFile = null;
try{
scanFile =new Scanner(file);
}catch(NumberFormatException | FileNotFoundException exception){
System.out.println("Error");
}
if (scanFile != null)
{
String[] numStrs = scanFile.nextLine().split(",");
int[] num = new int[numStrs.length];
for (int i =0; i <numStrs.length; i++)
{
if (i ==0)
{
System.out.println("Numbers");
}
else
{
numStrs = scanFile.nextLine().split("\\d+.,\\d+");
for (int j =0; j <numStrs.length; j++)
{
num[i] = Integer.parseInt(numStrs[i]);
}
System.out.println(num[i]);
}
}
}
You try to parse the second array numStrs with the first index i :
num[i] = Integer.parseInt(numStrs[i]);
So instead to that use this, change the numStrs[i] with numStrs[j]:
num[i] = Integer.parseInt(numStrs[j]);
Hope this can help you.

Duplicates in Array even though a Set was used

For a class project, we have to take a string(a paragraph),make it into an array of the individual words, and then make those words into objects of Object Array. The words cannot repeat so I used a Set to only get the unique values but only certain words are repeating! Here is the code for the method. Sorry for the vague description.
Private void processDocument()
{
String r = docReader.getLine();
lines++;
while(docReader.hasLines()==true)
{
r= r+" " +docReader.getLine();
lines++;
}
r = r.trim();
String[] linewords = r.split(" ");
while(linewords.length>words.length)
{
this.expandWords();
}
String[] newWord = new String[linewords.length];
for(int i=0;i<linewords.length;i++)
{
newWord[i] = (this.stripPunctuation(linewords[i]));
}
Set<String> set = new HashSet<String>(Arrays.asList(newWord));
Object[]newArray = set.toArray();
words = new Word[set.size()-1];
String newString = null;
for(int i =0;i<set.size();i++)
{
if(i==0)
{
newString = newArray[i].toString() + "";
}
else
{
newString = newString+newArray[i].toString()+" ";
}
}
newString = newString.trim();
String[] newWord2 = newString.split(" ");
for(int j=0;j<set.size()-1;j++)
{
Word newWordz = new Word(newWord2[j].toLowerCase());
words[j] = newWordz;
}
I believe the problem is when you put it into the HashSet the words are capitalized differently, causing the HashCode to be different. Cast everything to lowercase the moment you read it from the file and it should work.
newWord[i] = (this.stripPunctuation(linewords[i])).toLowerCase();
Try this:
public String[] unique(String[] array) {
return new HashSet<String>(Arrays.asList(array)).toArray();
}
Shamelessly copied from Bohemain's answer.
Also, as noted by #Brinnis, make sure that words are trimmed and in the right case.
for(int i = 0; i < linewords.length; i++) {
newWord[i] = this.stripPunctuation(linewords[i]).toLowerCase();
}
String[] newArray = unique(newWord);

Printing string array also prints null

When I am printing contents of a string array the output is printing 'null' as well. I am not sure what's wrong with this. Here is the output, what I expect is the output without 'null'
null(wa?>=0)nullnull*(wo?>=0)nullnull*(4*wa?+7*wo?>=50)nullnull*(d1=10)nullnull*((d2=1)+(k=2))nullnull
Thanks and appreciate your help. I would say my skill in Java in beginner level and I started two weeks back.
Here is the actual code:
String[] arrStr = new String[50];
int countStr = 0;
for (int i = 0; i < para.length; i++) {
if (para[i] == '(') {
count = count + 1;
}
if (para[i] == ')') {
count = count - 1;
}
if (count > 0) {
arrStr[countStr] = arrStr[countStr] + para[i];
} else {
if (para[i] == ')') {
arrStr[countStr] = arrStr[countStr] + para[i];
countStr += 1;
} else {
countStr += 1;
arrStr[countStr] = arrStr[countStr] + para[i];
// System.out.println(para[i]);
}
}
}
System.out.println(countStr);
for (int i = 0; i < countStr; i++) {
System.out.print(arrStr[i]);
}
Before this part, I am reading the following string from a word document:
(wa?>=0)AND(wo?>=0)AND(4*wa?+7*wo?>=50)AND(d1=10)AND((d2=1)+(k=2))
I think the problem may be due to the line:
arrStr[countStr] = arrStr[countStr] + para[i];
Since arrStr[countStr] is null initially and I add an element to it, it saves it as null+para[i]. Do you think it is possible?
Like when I try: System.out.println(arrStr[0]); I get the output as
null(wa?>=0)
System.out.println(null + "Bla");
prints nullBla. A null represented as String is "null". The issue here is that initially all your String[] is made of null. You need to initialize them first. Typically,
Arrays.fill(arrStr, "");
Should do.
If any element in arrStr is null while printing, it will print that faithfully.
Without knowing specifics in your code, you can either ensure that no element in your array becomes null (ensure that the lengths match up and you're not skipping element in arrStr, or check for null before printing the element.
You don't initialize the values of the arrStr array, you just allocate size for it, so each element of the array is null. When you assign a value to an element of the array, you concatenate its value (which is null) with the value of para[i].
You should initialize your array before using it:
String[] arrStr = new String[50];
for (int i = 0; i < arrStr.length; i++) {
arrStr[i] = "";
}

NullPointerException error while trying to remove a string word from an Array in a remove() method

I'm making this method remove() which takes a String word as argument, to delete from a global Array "words", but I keep getting a NullPointerException for some reason I cannot find, been stuck for hours.
Basically I check for if the word is in the first position, else if is in the last position, or else if it is in neither so I check all the array, and add the first half before the position of the word, and then add the second half after the position of the word in the array, as to skip it and "delete it". But I'm getting a NullPointerException in the for loop looking for the position of the word in the array. Code for the method is here:
public void remove(String a){
String[] temp_arr = new String[words.length-1]; // make array with 1 less length for deleted
if(words[0].equals(a)){ // if the word is the first in the array
for(int x=0, z=1; x<temp_arr.length; x++,z++)
temp_arr[x]=words[z];
words = temp_arr;
} else if(words[words.length-1].equals(a)){ // if the word is in the last position of the array
for(int x=0, z=0; x<temp_arr.length; x++,z++)
temp_arr[x] = words[z];
words = temp_arr;
} else{ // if the word is in neither first or last position of array
// THIS IS WHERE the exception is thrown, in this for loop, in the if(words[k].equals(a))
int k=0;
for (; k<words.length; k++){ // find the position of the word to delete
if (words[k].equals(a)) {
break;
}
}
for (int i = 0; i < k-1; i++){ // add first part of array before the word
temp_arr[i] = words[i];
}
for(int c = k, b = k+1; c< temp_arr.length; c++,b++){
temp_arr[c] = words[b];
}
words = temp_arr; // assign the new values to global array
}
}
Also, if theres any suggestions for good coding practice would be appreciated, thanks!
** I can only use Arrays as my data structure for this method.
Modify the condition like this
a.equals(words[0])
because you know the string value a. But dont know what value will come from array. So even null value comes from the array it does allow the null pointer exception.
I run your code and find a few errors, I correct somethings without changing the core idea:
} else { // if the word is in neither first or last position of array
// THIS IS WHERE the exception is thrown, in this for loop.
int k = -1;
for (int i = 0; i < words.length; i++) { // find the position of the word to delete
if (words[i].equals(a)) {
k=i;
break;
}
}
if(k<0)//if not exists
return;
for (int i = 0; i < k /*- 1*/; i++) { // add first part of array before the word
temp_arr[i] = words[i];
}
for (int i = k; i < temp_arr.length; i++) {
temp_arr[i] = words[i+1];
}
words = temp_arr; // assign the new values to global array
}
If the original array could't have null elements I would do like this:
public static String[] remove(String words[] , String a) {
int counter = 0;
for (int i = 0; i < words.length; i++) {
if( a.equals(words[i]) ){
words[i] = null;
counter++;
}
}
if(counter==0){
return words;
}
String[] words2 = new String[words.length - counter];
int i=0;
for (String string : words) {
if(string!=null){
words2[i++]=string;
}
}
return words2;
}
I would do that like this:
public void remove(String a) {
List<String> tmp = new ArrayList<String>();
for (String word : words) {
if ((word != null) && (word.equals(a))) {
continue;
}
tmp.add(word);
}
words = tmp.toArray(new String[]);
}
I have a question for you:
Why oh why are you using an array? You should always use a collection (eg a List) unless you absolutely have to use an array (which is rare indeed).
If it were a List, you wouldn't even need this method, because List has the remove() method that does all this for you!

Categories