2

I am currently getting an array out of bounds exception while executing the line name.firstName = this.firstNames[rand.nextInt(NUM_NAMES)]; Normally I dont have issues finding the source of these exceptions however I have been stuck on this one for some time now. Any help is appreciated, class and stacktrace are pasted below:

public class NameGenerator {
    private static final int NUM_NAMES = 200;
    private static final File NAMES_FILE = new File("resources/info.dat");

    /** a random number generator */
    private Random rand;

    /** the array of first names */
    private String[] firstNames;
    /** the array of last names */
    private String[] lastNames;

    /**
     * Default Constructor
     */
    public NameGen() {
        super();
        this.rand = new Random();

        try {
            readFile();
        } catch (IOException exp) {
            this.first = new String[] { "foo" };
            this.last = new String[] { "bar" };
        }
    }

    /**
     * Read the names from the file
     */
    private void readNFiles() throws IOException {
        List<String> tempFirst = new ArrayList<String>();
        List<String> tempLast = new ArrayList<String>();

        Scanner scnr = new Scanner(NAMES_FILE);

        while (scnr.hasNext()) {
            tempFirst.add(scnr.next());
            tempLast.add(scnr.next());
        }

        scnr.close();

        int size = tempFirst.size();

        this.first = new String[size];
        tempFirst.toArray(this.firstNames);

        this.last = new String[size];
        tempLast.toArray(this.last);
    }

    /**
     * @return a generated name
     */
    public FullName generateName() {
        FullName name = new FullName();
        name.first = this.firstNames[rand.nextInt()];

        name.last = this.lastNames[rand.nextInt()];
        return name;
    }

    /**
     * Class describing a full name
     */
    public static final class FullName {
        /** the first name */
        public String firstName;
        /** the last name */
        public String lastName;
    }
}
7
  • Maybe rand.nextInt(NUM_NAMES - 1)? Commented Sep 30, 2015 at 1:37
  • 1
    did not fix the issue :( Commented Sep 30, 2015 at 1:37
  • 1
    I don't see anywhere you call generateName. Consider providing a runnable example which demonstrates your problem. This is not a code dump, but an example of what you are doing which highlights the problem you are having. This will result in less confusion and better responses Commented Sep 30, 2015 at 1:38
  • You're also ignoring the IOException, making an array which is FAR below you expectations Commented Sep 30, 2015 at 1:39
  • 1
    I think you should also work with reality, rather then assumption, try using rand.nextInt(firstNames.length) (and rand.nextInt(lastNames.length)) instead Commented Sep 30, 2015 at 1:42

2 Answers 2

1

Based on...

try {

    readNamesFiles();

} catch (IOException exp) {

    this.firstNames = new String[] { "John" };
    this.lastNames = new String[] { "Doe" };

}

There is no guarantee that your arrays will contain NUM_NAMES elements (you should be logging the exception at the very least).

So using something like name.firstName = this.firstNames[rand.nextInt(NUM_NAMES)]; has the potional to cause some serious issues, as you've discovered.

Instead, you should work with reality instead of assumptions, using something more like...

name.firstName = this.firstNames[rand.nextInt(this.firstNames.length)];
Sign up to request clarification or add additional context in comments.

Comments

1

Here is a summary of your problematic code:

List<String> tempFirstNames = new ArrayList<String>(NUM_NAMES);
int size = tempFirstNames.size();

this.firstNames = new String[size];
FullName name = new FullName();
name.firstName = this.firstNames[rand.nextInt(NUM_NAMES)];

You are using rand.nextInt(NUM_NAMES) as the array index into firstNames. This will generate a number between 0 and NUM_NAMES. The problem is that there is no guarantee that the array firstNames will have a size of NUM_NAMES. As the @AngryProgrammer pointed out, you can use this instead:

name.firstName = this.firstNames[rand.nextInt(firstNames.length)];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.