Jump to content

'Word List' Assignment, out of bounds?

jackieAZ


// WordList class (compiles fine, but I get my error with the tester)

import java.util.ArrayList;
public class WordList {
  
  private ArrayList<String> words;
  private int count;
  
  //Constructor
    /*** TODO: Create new ArrayList and store in words
               Set count equal to 0 ***/
  public WordList()
  {
    words = new ArrayList<String>();
    count = 0;
  }  

  
// addWord method
/*** TODO: Check which case the word, w, presents to your current list
    (1) w is in the list - do not add
    (2) words is not full and w is not in the list - add w, increment count
    (3) words is full - create new String array with two times the space, 
                        copy data from words to new array, set words equal
                        to new array and then add w, increment count
    For all cases, return the current value of count ***/
  public int addWord(String w)
  {
    if (this.findWord(w) != -1)
    {
      return count;
    }
    else if(words.size() > count && this.findWord(w) == -1)
    {
      words.add(w);
      count++;
      return count;
    }
    else
    {
      ArrayList<String> newWords = new ArrayList<String>(words.size()*2);
      int i = 0;
      while (i<=words.size())
      {
        newWords.set(i, words.get(i));
        i++;
      }
      words = newWords;
      words.add(w);
      count++;
      return count;
    }
  }
  
      
// removeWord Method
/*** TODO: Find w in words. If found, move all elements to right of w one space to
               the left and decrement count. Otherwise, do nothing ***/
  public void removeWord(String input)
  {
      if (this.findWord(input) != -1)
      {
        count--;
        for(int y=words.indexOf(input);y<words.size();y++)
        {
          words.set(y, words.get(y+1));
        }
      }
  }
  

// findWord Method
/*** TODO: Loop over all words until w is found. Return index of w, or -1 if not
               found ***/
  public int findWord(String input)
  {
    int index= -1;
    for(int i=0;i<words.size();i++)
    {
      if (words.get(i).contains(input))
      {
        index = i;
        return index;
      }
    }
    return index;
  }
   

//equals Method 
   public boolean equals(int one, int two)
  {
     if (words.get(one).contains(words.get(two)))
     {
      return true;
     }
     else
     {
      return false;
     }
  }   

  

public String toString() {
    String s = "There are " + count + " word" + ((words.size() == 1)?"":"s") + " in the word list:\n";
    for (String w : words) {
      s = s + w + "\n";
    }
    return s;
  }

 
}

 

tester:


public class WordListTester
{
  public static void main(String [] args)
  {
    WordList list = new WordList();
    list.addWord("apple");
    list.addWord("letter");
    list.addWord("yes");
    
    
    System.out.println(list.findWord("yes"));
    System.out.println(list.equals(1, 2));
    list.removeWord("apple");
    System.out.println(list.toString());
  }
}

 

My error: 

java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
    at java.util.ArrayList.rangeCheck(Unknown Source)
    at java.util.ArrayList.get(Unknown Source)
    at WordList.addWord(WordList.java:43)
    at WordListTester.main(WordListTester.java:6)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:267)

 

I cannot for the life of me figure what the problem is here, is anyone able to identify the problem? I have a tendency as a noob programmer to miss obvious things, so sorry in advance haha

 

(on a side note, I am aware that I technically do not need to account for more space in 'words' because it is an ArrayList, but for the assignment I am required to do it this way (as a proof of concept if you will))

 

 

 

average fl studio fan vs average cubase enjoyer

 

rubber dome apologist

 

if you are reading this you are contracted the gae

 

Link to comment
Share on other sites

Link to post
Share on other sites

4 minutes ago, geo3 said:

Change while (i<=words.size()) to while (i<words.size())

 

Although you should really use a for each loop for this kind of situation.

I did, but was just trying to change it around to see if it affected my error at all (it didnt)

 

Changed it, didnt change anything

average fl studio fan vs average cubase enjoyer

 

rubber dome apologist

 

if you are reading this you are contracted the gae

 

Link to comment
Share on other sites

Link to post
Share on other sites

14 minutes ago, WubGuy said:

I did, but was just trying to change it around to see if it affected my error at all (it didnt)

 

Changed it, didnt change anything

Did that change where the error occurred though?

PSU Tier List | CoC

Gaming Build | FreeNAS Server

Spoiler

i5-4690k || Seidon 240m || GTX780 ACX || MSI Z97s SLI Plus || 8GB 2400mhz || 250GB 840 Evo || 1TB WD Blue || H440 (Black/Blue) || Windows 10 Pro || Dell P2414H & BenQ XL2411Z || Ducky Shine Mini || Logitech G502 Proteus Core

Spoiler

FreeNAS 9.3 - Stable || Xeon E3 1230v2 || Supermicro X9SCM-F || 32GB Crucial ECC DDR3 || 3x4TB WD Red (JBOD) || SYBA SI-PEX40064 sata controller || Corsair CX500m || NZXT Source 210.

Link to comment
Share on other sites

Link to post
Share on other sites

16 minutes ago, WubGuy said:

Changed it, didn't change anything

Then it has to be an empty arraylist, so even index 0 would be invalid. Print out the size of words before entering the while loop. Betting it's empty. This is why the for each loop exists. you could include && !isEmpty() in your loop test.

 

16 minutes ago, WubGuy said:

I did, but was just trying to change it around to see if it affected my error at all (it didnt)

There's no way a for each throws an IndexOutOfBoundsException. 

Link to comment
Share on other sites

Link to post
Share on other sites

Isn't the initial size of an ArrayList 10? or is there something im missing about what you mean

average fl studio fan vs average cubase enjoyer

 

rubber dome apologist

 

if you are reading this you are contracted the gae

 

Link to comment
Share on other sites

Link to post
Share on other sites

6 minutes ago, djdwosk97 said:

Did that change where the error occurred though?

nope, index 0 both times

average fl studio fan vs average cubase enjoyer

 

rubber dome apologist

 

if you are reading this you are contracted the gae

 

Link to comment
Share on other sites

Link to post
Share on other sites

7 minutes ago, djdwosk97 said:

Did that change where the error occurred though?

nope, index 0 both times

average fl studio fan vs average cubase enjoyer

 

rubber dome apologist

 

if you are reading this you are contracted the gae

 

Link to comment
Share on other sites

Link to post
Share on other sites

Just now, WubGuy said:

Isn't the initial size of an ArrayList 10? or is there something im missing about what you mean

But did you add any elements? I don't think you can address a non existent element regardless of the initial size. 

Link to comment
Share on other sites

Link to post
Share on other sites

4 minutes ago, geo3 said:

But did you add any elements? I don't think you can address a non existent element regardless of the initial size. 

yes, in the tester i add three elements before calling the other stuff

average fl studio fan vs average cubase enjoyer

 

rubber dome apologist

 

if you are reading this you are contracted the gae

 

Link to comment
Share on other sites

Link to post
Share on other sites

30 minutes ago, WubGuy said:

yes, in the tester i add three elements before calling the other stuff

It's failing on the first insert when you try to do newords.set(i, words.get(i)).

 

What you should be doing is first seeing if the word exists in the list (and if it does, just returning the count), if it doesn't, then call words.add(string) and increment the count. Basically get rid of the else clause in the addWord function and make the elseif clause the else clause.

 

If you want to leave the code the way it is, then you need to make two changes. 

First, make it "while (i<words.size())" in the else branch of addWord. 

Second, in the while loop do "newWords.add(words.get(i))" instead of "newWords.set(i, words.get(i))". Then it will work, although the only reason to use an arraylist instead of a normal array is because it has the ability to change size, so you really should just be appending onto the original arraylist rather than copying the data to a new list and then adding to that list. 

 

Also note that with your removeWord function that the other values in your arraylist still exist and the only thing keeping you from touching them is the fact that you have a counter keeping track of where the end of the valid list is. However, you're not using the count variable, but rather word.size(), so....yeah. So again you'd want to just call words.remove(input) and decrement the count. 

PSU Tier List | CoC

Gaming Build | FreeNAS Server

Spoiler

i5-4690k || Seidon 240m || GTX780 ACX || MSI Z97s SLI Plus || 8GB 2400mhz || 250GB 840 Evo || 1TB WD Blue || H440 (Black/Blue) || Windows 10 Pro || Dell P2414H & BenQ XL2411Z || Ducky Shine Mini || Logitech G502 Proteus Core

Spoiler

FreeNAS 9.3 - Stable || Xeon E3 1230v2 || Supermicro X9SCM-F || 32GB Crucial ECC DDR3 || 3x4TB WD Red (JBOD) || SYBA SI-PEX40064 sata controller || Corsair CX500m || NZXT Source 210.

Link to comment
Share on other sites

Link to post
Share on other sites

10 minutes ago, WubGuy said:

yes, in the tester i add three elements before calling the other stuff

Are you sure? 'java.lang.IndexOutOfBoundsException: Index: 0, Size: 0' Your exception says the size is 0, aka an empty arraylist. 

Link to comment
Share on other sites

Link to post
Share on other sites

Actually it looks like it's the newWords ArrayList that's causing the error.  I'm not really sure what your trying to accomplish in that loop with the newWords ArrayList so maybe double check that.

Link to comment
Share on other sites

Link to post
Share on other sites

1 minute ago, geo3 said:

Actually it looks like it's the newWords ArrayList that's causing the error.  I'm not really sure what your trying to accomplish in that loop with the newWords ArrayList so maybe double check that.

See my post right above yours, that might help shed some light on what he's trying to do.

PSU Tier List | CoC

Gaming Build | FreeNAS Server

Spoiler

i5-4690k || Seidon 240m || GTX780 ACX || MSI Z97s SLI Plus || 8GB 2400mhz || 250GB 840 Evo || 1TB WD Blue || H440 (Black/Blue) || Windows 10 Pro || Dell P2414H & BenQ XL2411Z || Ducky Shine Mini || Logitech G502 Proteus Core

Spoiler

FreeNAS 9.3 - Stable || Xeon E3 1230v2 || Supermicro X9SCM-F || 32GB Crucial ECC DDR3 || 3x4TB WD Red (JBOD) || SYBA SI-PEX40064 sata controller || Corsair CX500m || NZXT Source 210.

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, WubGuy said:

Isn't the initial size of an ArrayList 10? or is there something im missing about what you mean

When you call new ArrayList(), it creates an ArrayList with a size of 0, and some implementation defined capacity (which is 10 in OpenJDK, but could be anything). Similarly, calling new ArrayList(n) creates an ArrayList with size 0 and capacity n.

 

You're getting an error because when you add the first item, it goes through to

    else if(words.size() > count && this.findWord(w) == -1) // This fails because words.size() == 0
    {
      // ...
    }
    else
    {
      ArrayList<String> newWords = new ArrayList<String>(words.size()*2); // Constructing an ArrayList with capacity 0*2 = 0
      int i = 0;
      while (i<=words.size()) // This will go out of the bounds of the array, but I believe this was addressed earlier in the topic
      {
        newWords.set(i, words.get(i)); // But this is also a problem
        i++;
      }
      // ...
    }

Your problem is that you're treating ArrayList like an array. ArrayLists are Lists that happen to be implemented using an array, and Lists present a different style of interface to arrays. If you replace all of your code with the array equivalent (words, new String[words.length * 2], etc), it should work correctly. For the rest of this post, I'll assume that you need to use ArrayList, and explain how it differs from a plain array.

 

The difference between size and capacity

When you construct an ArrayList, it allocates an array behind the scenes. That array has size capacity, which defaults to 10, but can be whatever you pass into the constructor. Initially, you don't put anything in that array, so it has size of 0.

Each time you call .add() on the List, it increments size, which counts the actual number of items in your List, and each time you call .remove(n) it decrements size.

If an insertion into the list would cause size to be > capacity, that means we would be adding a new element off the end of the array in which the elements are stored, which wouldn't be allowed. To solve this, ArrayList will (automatically) double the size of the backing array, thereby doubling capacity (but not size), so that you can insert that item. This means that your code to handle doubling the List when you reach the limit isn't necessary - it will all be handled automatically.

 

Why you can't use .set(i, v)

Because ArrayList is a List rather than an array, the set method follows the interface defined in java.util.List. The relevant part of this definition is

Quote
Replaces the element at the specified position in this list with the specified element
 
Throws:
IndexOutOfBoundsException - if the index is out of range (index < 0 || index >= size())

This means that you can only use .set(i, v) to update values that have already been added to the List, not to add new items to it. This is the key difference between arrays and Lists - arrays let you add values anywhere within the defined size, whereas Lists are designed to let you append and pop, but not have sections without a value set (so you can't assign to indices 0, 1, 5, 6 - you need to use 0, 1, 2, 3).

The method that you want to use there is .add(v) rather than .set(i, v), because that is the method to use for adding new values rather than updating existing ones. However, in practice you don't need that at all, because the size doubling is provided for you by ArrayList.

HTTP/2 203

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×