Search code examples
javaloopssystem

ArrayIndexOutOfBounds on a object that should be in bounds


I have been stuck on getting my program to work for countless hours and just as I thought I got it all working it comes up with the ArrayIndexOutOfBounds. I do not understand why this is happening as its only on the first loop which is 0 0.A loop is essentially looking through an array of objects and then looking if each object is reserved (looking for a open plane seat). I will be posting a lot of code as a lot of my items are linked to other classes.

When I start the TrainSeatBookingApplication I answer the questions in order of p, m, f, s. So please use that order to debug as I have not fully finished other outcomes from what I know.

Train Seat Booking Application:

package exercises;
import java.util.Scanner;

public class TrainSeatBookingApplication {

    public static void main(String[] args) {
        SeatType theSeatType;
        FloorGrid floorType;
        TrainWay aTrainWay = null;
        TrainSmart aTrainSmart = null;
        Seat customerSeat;
        Seat trainSeats;
        char planeSizeChoice;
        char seatingArea;
        char seatEconomyOrFirst;
        char programBookingChoice;

        Scanner scan = new Scanner(System.in);
        System.out.println("Would you like to board a petite floor sized plane or a grande floor sized plane?");
        planeSizeChoice = Character.toLowerCase(scan.next().charAt(0));
        if (planeSizeChoice == 'p') {
            floorType = new PetiteFloorGrid();
            floorType.initialiseFloorGrid();
            System.out.println("Would you like to be in the middle, window or asile?");
            seatingArea= Character.toUpperCase(scan.next().charAt(0));
            if (seatingArea == 'M') {
                theSeatType = SeatType.MIDDLE;
            }
            else if (seatingArea == 'A') {
                theSeatType = SeatType.AISLE;
            }
            else {
                theSeatType = SeatType.WINDOW;
            }
            System.out.println("Would you like to be seated in first class or economy class?");
            seatEconomyOrFirst = Character.toUpperCase(scan.next().charAt(0));
            System.out.println("Would you like your seat to be booked via the smart program or the way program?");
            programBookingChoice = Character.toUpperCase(scan.next().charAt(0));
            if (seatEconomyOrFirst == 'F') {
                    if (programBookingChoice == 'S') {
                        customerSeat =  floorType.queryAvailableFirstClassSeat(theSeatType);
                        aTrainSmart.reserveFirstClass(planeSizeChoice, theSeatType);
                        System.out.println(floorType);
                    }
                    else {
                        customerSeat =  floorType.queryAvailableFirstClassSeat(theSeatType);
                        aTrainWay.reserveFirstClass(planeSizeChoice, theSeatType);
                        System.out.println(floorType);
                    }
                }
            else {

            }
            }
        else {
            floorType = new GrandeFloorGrid();
            floorType.initialiseFloorGrid();
            System.out.println("Would you like to be in the middle, window or asile?");
            seatingArea= Character.toUpperCase(scan.next().charAt(0));
            if (seatingArea == 'M') {
                theSeatType = SeatType.MIDDLE;
            }
            else if (seatingArea == 'A') {
                theSeatType = SeatType.AISLE;
            }
            else {
                theSeatType = SeatType.WINDOW;
            }
            System.out.println("Would you like to be seated in first class or middle class?");
            seatEconomyOrFirst = Character.toUpperCase(scan.next().charAt(0));
            System.out.println("Would you like your seat to be booked via the smart program or the way program?");
            programBookingChoice = Character.toUpperCase(scan.next().charAt(0));
            //System.out.println("Did not reach start of if");//testing program
            if (seatEconomyOrFirst == 'F') {
                if (programBookingChoice == 'S') {
                    customerSeat =  new Seat();
                    customerSeat = floorType.queryAvailableFirstClassSeat(theSeatType);
                    aTrainSmart.reserveFirstClass(planeSizeChoice, theSeatType);
                    System.out.println(floorType);
                }
                else {
                    customerSeat =  aTrainWay.reserveFirstClass(planeSizeChoice, SeatType.MIDDLE);
                    System.out.println(floorType);
                }
                //System.out.println("Did not go through either if or else");//testing program


    }
    }

}
}

Floor Grid:

package exercises;

abstract class FloorGrid {

    protected Seat[][] seat;
    protected int nRows;
    protected int nColumns;
    protected int nFirstClassRows;




    abstract protected void initialiseFloorGrid();

    public Seat getLeft(Seat seatx)
    {
        int column = seatx.getSeatPosition().getColumn();
        int row = seatx.getSeatPosition().getRow();
        column = column - 1;

        if (seat[column + 1][row].getSeatType() == seat[column][row].getSeatType()) {
            return seat[column][row];
        }           
        else {
            return null;
        }
    }
    public Seat getRight(Seat seatx)
    {
        int column = seatx.getSeatPosition().getColumn();
        int row = seatx.getSeatPosition().getRow();
        column = column + 1;
        if (seat[column - 1][row].getSeatType() == seat[column][row].getSeatType()) {
            return seat[column][row];
        }
        else {
            return null;
        }

    }
    ublic Seat queryAvailableFirstClassSeat(SeatType seatx)
{
    boolean found = false;
    int row;
    int column;

    int xMax = nRows + nFirstClassRows;
    int yMax = nColumns;
    seat = new Seat[xMax][yMax];

    for (int x = 0; x < xMax; x++) {
        for (int y = 0; y < yMax; y++) {
            seat = new Seat[x][y];
                if (seatx.getSpecificSeatType() == 2) /*2 is middle*/ {
                    if (!seat[x][y].isReserved()) {
                        if (seat[x][y].getFirstClass()) {
                            found = true;
                            column = seat[x][y].getSeatPosition().getColumn();
                            row = seat[x][y].getSeatPosition().getRow();
                            return seat[x][y];
                        }
                    }
                }
                else if(seatx.getSpecificSeatType() == 3) { //3 is windows
                    if (!seat[x][y].isReserved()) {
                        if (seat[x][y].getFirstClass()) {
                            found = true;
                            column = seat[x][y].getSeatPosition().getColumn();
                            row = seat[x][y].getSeatPosition().getRow();
                            return seat[x][y];
                        }
                    }
                }
                else if (seatx.getSpecificSeatType() == 1) { // 1 is aisle
                    if (!seat[y][x].isReserved()) {
                        if (seat[y][x].getFirstClass()) {
                            found = true;
                            column = seat[x][y].getSeatPosition().getColumn();
                            row = seat[x][y].getSeatPosition().getRow();
                            return seat[x][y];
                        }
                    }
                }
                else if (seatx.getSpecificSeatType() == 10) {
                        if (!seat[y][x].isReserved()) {
                            if (seat[y][x].getFirstClass()) {
                                found = true;
                                column = seat[x][y].getSeatPosition().getColumn();
                                row = seat[x][y].getSeatPosition().getRow();
                                return seat[x][y];
                            }
                        }
                    }
                if (x == (nRows - 1) & y == (nColumns = 1) & found == false) { //this checks to see if the loop is looping through the last seat. If it is and no open seat has been found it returns null
                    return null;
                }
        }
    }
    return null;

}

}
public Seat getSeat(int seatRow, char seatPosition)
{
    return null;

}

}

Petite Floor Grid:

    package exercises;
   package exercises;

public class PetiteFloorGrid extends FloorGrid {
    Seat[][] newSeats;

    public PetiteFloorGrid () {
        this.nColumns = 7;
        this.nRows = 10;
        this.nFirstClassRows = 4;

        this.initialiseFloorGrid(); 
        }


    protected void initialiseFloorGrid() {
     int xMax = nRows + nFirstClassRows;
     int yMax = nColumns;
     newSeats = new Seat[xMax][yMax];

        for (int x = 0; x < xMax; x++) {
            for (int y = 0; y < yMax; y++) {
                Seat seat = new Seat();
                seat.setReserved(false);
                if (x < 4) {
                    seat.setFirstClass(true);
                }
                if (y > 1 & y < 5) {
                    seat.setSeatType(SeatType.MIDDLE);
                }
                else if (y < 1 & y > 5)  {
                    seat.setSeatType(SeatType.WINDOW);
                }
                else {
                    seat.setSeatType(SeatType.AISLE);
                }

                SeatPosition aSeatPosition = new SeatPosition(x, (char) ('A' + y));
                seat.setSeatPosition(aSeatPosition);;
                newSeats[x][y] = seat;

            }
        }
    }

    public Seat[][] initialisedSeat() {
        return newSeats;
    }


}

Seat Class:

package exercises;

public class Seat {


private boolean firstClass;
private boolean reserved;
private SeatType seatType;
private SeatPosition seatPosition;

public Seat(SeatPosition seatPosition,  SeatType seatType, boolean reserved, boolean firstClass)
{
    this.seatPosition = seatPosition;
    this.seatType = seatType;
    this.reserved = reserved;
    this.firstClass = false;
}
public Seat(SeatPosition seatPosition, boolean reserved, boolean firstClass)
{
    this.seatPosition = seatPosition;
    this.seatType = SeatType.AISLE;
    this.reserved = reserved;
    this.firstClass = false;
}
public Seat() {
    SeatPosition aSeatPosition = new SeatPosition(1,'a');
    this.seatPosition = aSeatPosition;
    this.seatType = SeatType.AISLE;;
    this.reserved = false;
}
public SeatType getSeatType()
{
    return this.seatType;
}

public void setSeatType(SeatType seattype) {
this.seatType = seattype;
}

public boolean getFirstClass() {
    return this.firstClass;
}

public boolean isFirstClass()
{
    if (firstClass == true)
    {
        return true;
    }
    else
    {
        return false; 
    }
}
public void setFirstClass(boolean trueOrNot) {
    this.firstClass = trueOrNot;
}
public boolean isReserved()
{
    if (reserved == true)
    {
        return true;
    }
    else
    {
        return false; 
    }
}

public void setReserved(boolean reserved)
{
    this.reserved = reserved;
}

public SeatPosition getSeatPosition()
{
    return this.seatPosition;
}

public void setSeatPosition(SeatPosition aSeatPosition) {
    this.seatPosition = aSeatPosition;
}

public String toDescription()
{
    String typeClass;
    String bookedOrNot;

    if (firstClass == true)
    {
        typeClass = "First Class"; 
    }
    else
    {
        typeClass = "Economy Class";
    }
    if (reserved == true) {
        bookedOrNot = "";
    }
    else {
        bookedOrNot = " not ";
    }

    return ""+typeClass+" "+seatType+"seat at: "+seatPosition.getColumn()+""+seatPosition.getRow()+" is"+bookedOrNot+"booked";      
}

public String toString()
{
    char reservedOrNot;
    char firstClassOrNot;

    if (firstClass == true)
    {
        if (seatType.toString().equals(SeatType.AISLE)) {
            firstClassOrNot = 'A';
        }
        else if (seatType.toString().equals(SeatType.MIDDLE)) {
            firstClassOrNot = 'M';
        }
        else if (seatType.toString().equals(SeatType.WINDOW)) {
            firstClassOrNot = 'W';
        }
        else {
            firstClassOrNot = 'X';
        }
    }
    else
    {
        if (seatType.toString().equals(SeatType.AISLE)) {
            firstClassOrNot = 'a';
        }
        else if (seatType.toString().equals(SeatType.MIDDLE)) {
            firstClassOrNot = 'm';
        }
        else if (seatType.toString().equals(SeatType.WINDOW)) {
            firstClassOrNot = 'w';
        }
        else {
            firstClassOrNot = 'x';
        }
    }


    if (reserved == true)
    {
        reservedOrNot = 'X';
    }
    else
    {
        reservedOrNot = '_';
    }

    return "["+firstClassOrNot+" "+reservedOrNot+"]";
}
}

Seat Type:

package exercises;

public enum SeatType {

    WINDOW(3),MIDDLE(2),AISLE(1);

    private int option;

    private SeatType(int option)
    {
        this.setSeatType(option);
    }
    private SeatType()
    {
    }

    public int getSeatType()
    {
        return this.option;
    }

    public void setSeatType(int option)
    {
        this.option = option;
    }

    public int getSpecificSeatType() {
        return this.getSeatType();
    }

}

Train Smart:

    package exercises;

public class TrainSmart extends TrainOperator {
    private Seat aSeat;
    private int foundFClass = 1;
    private int foundEClass = 1;
    private String sameAsWindow;
    private String sameAsAisle;
    PetiteFloorGrid aPetiteFloor = new PetiteFloorGrid();

    public PetiteFloorGrid getPetiteFloor() {
        return this.aPetiteFloor;
    }

    @Override
    public Seat reserveFirstClass(char chosenGrid, SeatType aType) {

        if (aType == SeatType.WINDOW) {
            sameAsWindow = "yes";
        }
        else if(aType == SeatType.AISLE) {
            sameAsAisle = "yes";
        }

        System.out.println("Outside If, attempting to enter");
        if (chosenGrid == 'P') { //checks if the user specified grid is P for petite, if not carries on untill grand
        System.out.println("Inside if");
            if (aPetiteFloor.queryAvailableFirstClassSeat(aType) != null) { //Checks if seat of specified type is free, if so then it books it
                aSeat = aPetiteFloor.queryAvailableFirstClassSeat(aType);
                aSeat.setReserved(true);
                foundFClass = 2;
                return aSeat;
            }
            else if (aPetiteFloor.queryAvailableFirstClassSeat(SeatType.WINDOW) != null & sameAsAisle.equals("yes")) {
                aSeat = aPetiteFloor.queryAvailableFirstClassSeat(SeatType.WINDOW);
                foundFClass = 2;
                if (aPetiteFloor.getLeft(aSeat) != null) {
                    aSeat = aPetiteFloor.getLeft(aSeat);
                }
                else {
                    aSeat = aPetiteFloor.getRight(aSeat);
                }
                aSeat.setReserved(true);
                return aSeat;
            }
            else if (aPetiteFloor.queryAvailableFirstClassSeat(SeatType.AISLE) != null & sameAsWindow.equals("yes")) {
                aSeat = aPetiteFloor.queryAvailableFirstClassSeat(SeatType.AISLE);
                foundFClass = 2;
                if (aPetiteFloor.getLeft(aSeat) != null) {
                    aSeat = aPetiteFloor.getLeft(aSeat);
                }
                else {
                    aSeat = aPetiteFloor.getRight(aSeat);
                }
                aSeat = aPetiteFloor.getLeft(aSeat);
                aSeat.setReserved(true);
                return aSeat;
            }
            return null;
        }
        else {
            GrandeFloorGrid aGrandeFloor = new GrandeFloorGrid();

                if (aGrandeFloor.queryAvailableFirstClassSeat(aType) != null) { //Checks if seat of specified type is free, if so then it books it
                    aSeat = aGrandeFloor.queryAvailableFirstClassSeat(aType);
                    aSeat.setReserved(true);
                    foundFClass = 2;
                    return aSeat;
                }
                else if (aGrandeFloor.queryAvailableFirstClassSeat(SeatType.WINDOW) != null & sameAsAisle.equals("yes")) {
                    aSeat = aGrandeFloor.queryAvailableFirstClassSeat(SeatType.WINDOW);
                    foundFClass = 2;
                    if (aGrandeFloor.getLeft(aSeat) != null) {
                        aSeat = aGrandeFloor.getLeft(aSeat);
                    }
                    else {
                        aSeat = aGrandeFloor.getRight(aSeat);
                    }
                    aSeat.setReserved(true);
                    return aSeat;
                }
                else if (aGrandeFloor.queryAvailableFirstClassSeat(SeatType.AISLE) != null & sameAsWindow.equals("yes")) {
                    aSeat = aGrandeFloor.queryAvailableFirstClassSeat(SeatType.AISLE);
                    foundFClass = 2;
                    if (aGrandeFloor.getLeft(aSeat) != null) {
                        aSeat = aGrandeFloor.getLeft(aSeat);
                    }
                    else {
                        aSeat = aGrandeFloor.getRight(aSeat);
                    }
                    aSeat = aGrandeFloor.getLeft(aSeat);
                    aSeat.setReserved(true);
                    return aSeat;
                }
                return null;
        }
    }

    @Override
    public Seat reserveEconomyClass(char chosenGrid, SeatType aType) {
        if (aType == SeatType.WINDOW) {
            sameAsWindow = "yes";
        }
        else if(aType == SeatType.AISLE) {
            sameAsAisle = "yes";
        }

        if (chosenGrid == 'P') { //checks if the user specified grid is P for petite, if not carries on untill grand
        PetiteFloorGrid aPetiteFloor = new PetiteFloorGrid();

            if (aPetiteFloor.queryAvailableEconomySeat(aType) != null) { //Checks if seat of specified type is free, if so then it books it
                aSeat = aPetiteFloor.queryAvailableEconomySeat(aType);
                aSeat.setReserved(true);
                foundFClass = 2;
                return aSeat;
            }
            return null;
        }
        else {
            GrandeFloorGrid aGrandeFloor = new GrandeFloorGrid();

                if (aGrandeFloor.queryAvailableEconomySeat(aType) != null) { //Checks if seat of specified type is free, if so then it books it
                    aSeat = aGrandeFloor.queryAvailableEconomySeat(aType);
                    aSeat.setReserved(true);
                    foundFClass = 2;
                    return aSeat;
                }
                return null;
        }
    }

}

Grande Floor Grid Class:

package exercises;

public class GrandeFloorGrid extends FloorGrid {
    Seat[][] newSeats;
    public GrandeFloorGrid () {
        this.nColumns = 9;
        this.nRows = 12;
        this.nFirstClassRows = 6;
    }


    @Override
    protected void initialiseFloorGrid() {
         int xMax = nRows + nFirstClassRows;
         int yMax = nColumns;
         newSeats = new Seat[xMax][yMax];

            for (int x = 0; x < xMax; x++) {
                for (int y = 0; y < yMax; y++) {
                    Seat seat = new Seat();
                    seat.setReserved(false);
                    if (x < 6) {
                        seat.setFirstClass(true);
                    }
                    if (y > 2 & y < 6) {
                        seat.setSeatType(SeatType.MIDDLE);
                    }
                    else if (y < 2 & y > 6)  {
                        seat.setSeatType(SeatType.WINDOW);
                    }
                    else {
                        seat.setSeatType(SeatType.AISLE);
                    }

                    SeatPosition aSeatPosition = new SeatPosition(x, (char) ('A' + y));
                    seat.setSeatPosition(aSeatPosition);;
                    newSeats[x][y] = seat;

                }

            }
    }
}

The error occurs once I have answered the "Would you like your seat to be booked via the smart program or the way program?" and it then goes into a if statement that has the code "customerSeat = floorType.queryAvailableFirstClassSeat(theSeatType);" which opens up FloorGrid.java and gets to line 135 then the error comes up "Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0".

I would really appreciate all help, I have bee trying to fix this for the whole day now.

This question has not been aswered already. Reason is, because in that question one can easily see that they have <= which should always be <. My parramaters are

for (int y = 0; y < nRows; ++y) {
     for (int x = 0; x < nColumns; ++x) {

I believe that is not the issue.

I have solved two of my errors already, I however still have a couple left that are puzzling me.

Problems

This line of code in TrainWay.Java:

aPetiteFloor.queryAvailableFirstClassSeat(aType.values()[+chosen]) != null

As well as its equivalent (if users choses Grande Floor Size):

aGrandeFloor.queryAvailableFirstClassSeat(aType.values()[+chosen]) != null.

Will always output this error:

java.lang.NullPointerException

Secondly, if I chose w as the last ooption when asked about which program I would like to use to book my train ride it, after entering your input, will just do nothing. Almost as if the scanner is taking infinite input.

Now after a lot of stepping, if I can remember correctly, this while loop in the TrainWay system seems to be stuck on a infinite loop:

    while (foundEClass == 1 & (chosen < 4) ) { //This algorithm checks each enum type SeatType and if there is a available seat on each type

        if (aPetiteFloor.queryAvailableEconomySeat(aType.values()[+chosen]) != null) {
            aSeat = aPetiteFloor.queryAvailableEconomySeat(aType.values()[+chosen]);
            aSeat.setReserved(true);


    foundEClass = 2;
                if (foundEClass == 2) {
                    return aSeat;
                }
            }
            ++chosen;
        }

It seems to execute the while bit of code and once it checks the if parameters and finds that its false then it just repeats straight away without looking at any of the other code (++chosen and other if).

This leads me to find the biggest problem which is more to do with programming concepts. The initialiseFloorGrid() method in both PetitieFloorGrid.java and GrandeFloorGrid.Java do everything I want them to do. They map out the whole plane with seat numbers, if its reserved and what area its in etc. However, I really do not know how to use the seats that I have generated with the initialiseFloorGrid() in the superclass that it extends, FloorGrid. (FloorGrid holds the Query method which is used in the TrainWay.java as a parameter in the while loop that keeps looping.

So If I can figure out how to use the seats created in Petite/GrandeFloorGrid in FloorGrid then I can fix the whole TrainWay.java method.


Solution

  • The iteration itself isn't an issue. Take a look at how you initialize the floor grid

    @Override
    protected void initialiseFloorGrid() {
        for (int y = 0; y < nRows + nFirstClassRows; ++y) {
            for (int x = 0; x < nColumns; ++x) {
                //newSeats[y][x].getSeatPosition().setSeatPosition(nRows, (char) ('A' + nColumns));
                newSeats = new Seat[y][x]; 
                newSeats[y][x].setReserved(false);
            }
        }
    }
    
    1. The newSeats variable is initialized every time.
    2. An out of bounds exception indicates you're looking for an array index that is greater than what is actually there. Initialize the array and then populate it.
    3. x - rows
    4. y - cols

    Consider the following:

    @Override
    protected void initialiseFloorGrid() {
        int xMax = nRows + nFirstClassRows;
        int yMax = nColumns;
        newSeats = new Seat[xMax][yMax];
        for (int x = 0; x < xMax; x++) {
            for (int y = 0; y < yMax; y++) {
                Seat seat = new Seat();
                seat.setReserved(false);
                newSeats[x][y] = seat;
            }
        }
    }