ArrayIndexOutOfBounds Exception Error When Displaying Reservations After Booking - Java - java

I'm making a reservation feature for my events, and I can successfully add the attendee, however when I want to display the details for every attendee, it gives me a ArrayIndexOutOfBounds exception error, which I'm not quite sure how to fix.
Main.java
private static Scanner sc = new Scanner(System.in);
private static int eventCreationLimit = 5;
private static Event[] events = new Event[eventCreationLimit];
private static int eventsCreated;
public static void main(String args[]) {
String input;
// Main menu.
do {
System.out.println("\n~ BOOKING SYSTEM ~");
System.out.println("------------------");
System.out.println("A. Schedule an Event");
System.out.println("B. Add an Attendee");
System.out.println("C. View Reservations");
System.out.println("X. Exit\n");
System.out.print("Select an option: ");
input = sc.nextLine();
switch (input.toUpperCase()) {
case "A":
scheduleAnEvent();
break;
case "B":
addAttendee();
break;
case "C":
displayReservations();
break;
case "X":
System.out.println("INFO: You have exited the booking system.");
break;
default:
System.out.println("ERROR: Invalid input!");
}
} while (!input.equalsIgnoreCase("X"));
}
private static void scheduleAnEvent() {
System.out.println("\n~ SCHEDULE A EVENT ~");
System.out.println("--------------------");
System.out.print("Enter the ID: ");
String ID = sc.nextLine();
...
System.out.print("Enter the attendee limit: ");
int attendeeLimit = Integer.parseInt(sc.nextLine());
// Add the new event to the array.
events[eventsCreated++] = new Event(ID, ..., attendeeLimit, attendeeLimit, ...);
for (int i = 0; i < eventsCreated; i++)
// Set the places available for the specific event being created to subtract it later when an attendee is added.
if (ID.equals(events[i].getID()))
// The number of places available left in the event can be displayed by going to "B. View All Events".
events[i].setPlacesAvailable(attendeeLimit);
// Give the user a confirmation message.
System.out.println("\nINFO: Sucessfully created Event: " + ID + ".");
}
private static void addAttendee() {
Event event = null;
boolean result = false;
System.out.println("\n~ ADD AN ATTENDEE ~");
System.out.println("-------------------");
System.out.print("Enter attendee name: ");
String name = sc.nextLine();
System.out.print("Enter attendee phone number: ");
String phone = sc.nextLine();
Attendee a = new Attendee(name, phone);
System.out.print("Enter event ID: ");
String eventID = sc.nextLine();
// Check if the given ID matches an event.
for (int i = 0; i < eventsCreated; i++)
if (events[i].getID().equals(eventID))
event = events[i];
if (event != null) {
if (event.getID().equals(eventID)) {
result = ((Event) event).addAttendee(a);
if (result) {
// If the event has enough room, then add the attendee.
System.out.println("INFO: Attendee successfully added to Event: " + eventID + ".");
displayReservations();
}
else
// If the event is full, then the attendee will not be added.
System.out.println("ERROR: The Event: " + eventID + " is full, the attendee could not be added.");
} else
System.out.println("ERROR: The given ID does not match any existing event.");
} else
System.out.println("ERROR: The event was not found.");
}
private static void displayReservations() {
System.out.println("\n~ RESERVATIONS ~");
System.out.println("----------------");
String pattern = "%-18s %-18s %-22s %-1s\n";
System.out.printf(pattern, "NAME", "PHONE", "EVENT ID", "FEE");
System.out.println("----------------------------------------------------------------");
// Display all reservations for events.
for (int i = 0; i < events[i].getAttendeeCount(); i++)
events[i].displayReservations();
}
Event.java
...
private String ID;
private int attendeeLimit;
private int attendeeCount;
private int placesAvailable;
private Attendee[] a = new Attendee[attendeeCount];
public Demonstration(..., String ID, int placesAvailable, int attendeeLimit, ...) {
this.ID = ID;
this.placesAvailable = placesAvailable;
this.attendeeLimit = attendeeLimit;
}
public String getID() { return this.ID; }
public int getPlacesAvailable() { return this.placesAvailable; }
public int getAttendeeLimit() { return this.attendeeLimit; }
public void setPlacesAvailable(int placesAvailable) { this.placesAvailable = placesAvailable; }
public boolean addAttendee(Attendee at) {
// Proceed to add the attendee if there is enough room.
if (attendeeCount <= placesAvailable) {
attendeeCount++;
// Decrease the number of places available by one.
setPlacesAvailable(placesAvailable - 1);
return true;
}
return false;
}
public void displayReservations() {
System.out.println("ID: " + ID);
if (attendeeCount > 0)
for (int i = 0; i < attendeeCount; i++)
a[i].attendeeDetails();
}
Attendee.java
private String name;
private String phone;
public Attendee(String name, String phone) {
this.name = name;
this.phone = phone;
}
public String getName() { return this.name; }
public String getPhone() { return this.phone; }
public void attendeeDetails() {
System.out.println("Name: " + name);
System.out.println("Phone: " + phone);
}
The above code gives me a ArrayIndexOutOfBoundsException error in the displayReservations() method (a[i].attendeeDetails()) whenever I try to add an attendee to an event.
Problem: How do I display all reservation details for all events? Thank you for your help!
EDIT
The error:
Index 0 out of bounds for length 0.

There are a couple of issues with your code:
You are maintaining an attendeeCount separately than the size of the Attendee[], but in your addAttendee() method, you never actually add the new Attendee to the array
Because Attendee[] is an array, it can't grow larger than the size when first initialized. If you want to use an array, instead of an ArrayList that can grow dynamically, you need to initialize the array to the maximum size: placesAvailable:
So, my recommendation would be to switch from using an array to an ArrayList by importing java.util.Arraylist, changing the declaration of the Attendee[] to an ArrayList, and updating the rest of the Event.java code to use the ArrayList, as well as making sure you add the new Attendee in the addAttendee() method. Finally, you don't need to maintain the attendee count separately, just ask the attendees ArrayList it's current size.
Event.java
...
import java.util.*; //You can import all java.util classes
private String ID;
private int attendeeLimit;
private int placesAvailable;
private List<Attendee> attendees = new ArrayList<>(); //Initialize the attendees ArrayList
public Demonstration(..., String ID, int placesAvailable, int attendeeLimit, ...) {
this.ID = ID;
this.placesAvailable = placesAvailable;
this.attendeeLimit = attendeeLimit;
}
public String getID() { return this.ID; }
public int getPlacesAvailable() { return this.placesAvailable; }
public int getAttendeeLimit() { return this.attendeeLimit; }
public void setPlacesAvailable(int placesAvailable) { this.placesAvailable = placesAvailable; }
public boolean addAttendee(Attendee at) {
// Proceed to add the attendee if there is enough room.
if (attendeeCount <= placesAvailable) {
attendees.add(at); //Make sure you add the new Attendee to the list
// Decrease the number of places available by one.
setPlacesAvailable(placesAvailable - 1);
return true;
}
return false;
}
public void displayReservations() {
System.out.println("ID: " + ID);
int attendeeCount = attendees.size(); //Calculate the number of Attendees
if (attendeeCount > 0)
for (int i = 0; i < attendeeCount; i++)
attendees.get(i).attendeeDetails();
}

attendeCount does not have a value as at the time you creating the Array "a". For what you are trying to achieve, I suggest:
i. Use an Arraylist.
ii. Initialize you array in the constructor to attendeLimit.
If possible, I also suggest you use parameter methods where neccessary.

Related

Using indexOf() method for ArrayList of objects

In my program, I have a Vendor class and a Hospital class and store instances of these classes in arraylists called vendors and hospitals. My Vendor class has a string array with names of hospitals that correspond to instances of the Hospital class. I'm trying to find a way to go from the name of the hospital in the string array that is part of the Vendor class, to getting the index value of that hospital for the hospitals arraylist. Apologies if this post doesn't make much sense, I'm very new to coding. Any help would be greatly appreciated.
Edit: Please Ctrl+F with the following to jump to the particular lines of code in question
//check if hospital
Vendor Class
package com.company;
import java.util.Arrays;
import java.util.Scanner;
public class Vendor {
//static variables are the same for all vendor instances
static int numOfHospitals;
static int numOfAppointments;
//non-static variables are specific to one vendor instance
int priorityNum;
String salespersonName;
String vendorCompanyName;
String [] vendorPicks;
String[] vendorSchedule;
public void printVendorSchedule() {
System.out.println(Arrays.toString(vendorSchedule));
}
public void printVendorPicks () {
System.out.println(Arrays.toString(vendorPicks));
}
public String getVendorSchedule (int appointmentSlot) {
return vendorSchedule [appointmentSlot];
}
public String getVendorPick (int currentHospitalPick) {
return vendorPicks[currentHospitalPick];
}
public boolean checkVendorSchedule (int appointmentSlot) {
return ((vendorSchedule[appointmentSlot]).equals("open"));
}
public void setVendorAppointment (int appointmentSlot, String hospitalName) {
vendorSchedule[appointmentSlot] = hospitalName;
}
public Vendor createNewVendor(int priorityNum, int numOfAppointments, int numOfHospitals, String salespersonName, String vendorCompanyName){
this.priorityNum=priorityNum;
this.salespersonName=salespersonName;
this.vendorCompanyName=vendorCompanyName;
this.vendorPicks = new String[numOfHospitals];
this.vendorSchedule = new String[numOfAppointments];
for (int i = 0; i <numOfAppointments; i++) {
this.vendorSchedule[i] = "open";
}
Scanner input = new Scanner(System.in);
Vendor vendorToAdd = new Vendor();
//loop to add vendor's hospital picks
int counter = 0;
while (counter < numOfHospitals) {
System.out.println("Enter the #" +(counter+1) +" hospital for "+salespersonName+". If there are no more hospitals for this vendor, enter Done.");
String placeHolder = input.nextLine();
if (placeHolder.equalsIgnoreCase("done")) {
break;
}
vendorPicks[counter]=placeHolder;
counter++;
}
return vendorToAdd;
}
}
Hospital Class
package com.company;
import java.util.Scanner;
import java.util.Arrays;
import java.util.ArrayList;
public class Hospital {
//static variables here
int numOfAppointments;
int numOfHospitals;
//non-static variables here
String nameHospital;
String nameDirector;
String [] hospitalSchedule;
public void printHospitalSchedule () {
System.out.println(Arrays.toString(hospitalSchedule));
}
public String getHospitalSchedule(int appointmentSlot) {
return hospitalSchedule[appointmentSlot];
}
public boolean checkHospitalSchedule (int appointmentSlot) {
return ((hospitalSchedule[appointmentSlot]).equals("open"));
}
public void setHospitalAppointment (int appointmentSlot, String nameVendor) {
hospitalSchedule[appointmentSlot] = nameVendor;
}
public Hospital createNewHospital(int numOfAppointments, int numOfHospitals,
String nameHospital, String nameDirector) {
Hospital h1 = new Hospital();
this.nameDirector=nameDirector;
this.nameHospital=nameHospital;
this.hospitalSchedule = new String[numOfAppointments];
for (int i=0; i < numOfAppointments; i++) {
hospitalSchedule[i] = "open";
}
return h1;
}
}
Main Class
package com.company;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// Inputting #vendors, #hospitals
int vendorCounter=1;
System.out.println("Enter the total number of appointment slots.");
Scanner myScanner = new Scanner(System.in);
int numOfAppointments = Integer.parseInt(myScanner.nextLine());
System.out.println("Enter the total number of hospitals in the draft.");
int numOfHospitals = Integer.parseInt(myScanner.nextLine());
ArrayList<Hospital> hospitals = new ArrayList<Hospital>();
//creating hospitals
int hospitalCounter = 1;
while (hospitalCounter <=numOfHospitals) {
System.out.println("Enter the name of hospital #" + hospitalCounter);
String currentHospitalName = myScanner.nextLine().toLowerCase(Locale.ROOT).trim();
System.out.println("Enter the director's name for " + currentHospitalName + ".");
String currentDirectorName = myScanner.nextLine().toLowerCase(Locale.ROOT).trim();
Hospital h1 = new Hospital();
h1.createNewHospital(numOfAppointments, numOfHospitals, currentHospitalName, currentDirectorName);
hospitals.add(h1);
hospitalCounter++;
}
//creating vendors
ArrayList<Vendor> vendors = new ArrayList<Vendor>();
Scanner myInput = new Scanner(System.in);
while (vendorCounter != 2000){
System.out.println("Are you entering a new vendor? Enter Yes or No");
String isAddingNewVendor;
isAddingNewVendor= myScanner.nextLine();
if (isAddingNewVendor.equalsIgnoreCase("yes"))
{
System.out.println("Enter the name of the salesperson.");
String salespersonName = myInput.nextLine();
System.out.println("Enter the company name for "+salespersonName+".");
String vendorCompanyName = myInput.nextLine();
Vendor v1 = new Vendor();
v1.createNewVendor(vendorCounter, numOfAppointments, numOfHospitals,salespersonName,vendorCompanyName);
vendors.add(v1);
vendorCounter++;
}
else vendorCounter = 2000;
}
/* System.out.println(vendors.get(0).vendorCompanyName);
System.out.println(hospitals.get(0).nameHospital);
System.out.println(vendors.get(0));
vendors.get(0).printVendorSchedule();
vendors.get(0).printVendorPicks();
hospitals.get(0).printHospitalSchedule();
if (vendors.get(0).checkVendorSchedule(0)) {
System.out.println ("This appointment slot is open for the vendor.");
}
if (hospitals.get(0).checkHospitalSchedule(0)) {
System.out.println("This appointment slot is open for the hospital.");
}*/
for (int i = 0; i < numOfHospitals; i++) {
System.out.println("Information for hospital #" + i);
System.out.println("Hospital name: " +hospitals.get(i).nameHospital);
System.out.println("Director's name: " + hospitals.get(i).nameDirector);
System.out.println("The hospital's initial schedule:");
hospitals.get(i).printHospitalSchedule();
}
for (int i = 0; i < vendors.size(); i++) {
System.out.println("Information for vendor #" + i);
System.out.println("Salesperson's name: "+vendors.get(i).salespersonName);
System.out.println("Company name: " + vendors.get(i).vendorCompanyName);
System.out.println("The vendor's hospital choices:");
vendors.get(i).printVendorPicks();
System.out.println("The vendor's initial schedule:");
vendors.get(i).printVendorSchedule();
}
//draft loop logic
int draftRound = 1;
while (draftRound <= numOfAppointments) {
if (draftRound % 2 == 1) {
//insert code for odd-numbered draft rounds here.
//these rounds should start with picker 1, then 2, 3, etc.
int currentVendor = 0; //starts this round with the first vendor
while (currentVendor < vendors.size()){
//this while loop continues running through a single draft round until all vendors get a pick
int currentAppointmentSlot = 0;
int currentVendorPickSlot=0;
while (currentVendorPickSlot < numOfHospitals) { //this loops through a single vendor until all appointments checked or appt assigned
//check if hospital and vendor are both open
String currentHospital = vendors.get(currentVendor).vendorPicks[currentVendorPickSlot];
System.out.println(currentHospital);
int currentHospitalsIndex = hospitals.indexOf(currentHospital); //indexof is returning -1 creating the exceptionoutofbounds
System.out.println("Current hospital index:"+ currentHospitalsIndex);
if ( hospitals.get(currentHospitalsIndex).checkHospitalSchedule(currentAppointmentSlot) != vendors.get(currentVendor).checkVendorSchedule(currentAppointmentSlot)) {
currentAppointmentSlot++;
}
else {
vendors.get(currentVendor).setVendorAppointment(currentVendorPickSlot, hospitals.get(currentHospitalsIndex).nameHospital);
hospitals.get(currentHospitalsIndex).setHospitalAppointment(currentVendorPickSlot, vendors.get(currentVendor).salespersonName);
break; // does this break the loop?
}
}
currentVendor++;
}
draftRound++;
}
if (draftRound % 2 == 0) {
//insert code for even-numbered draft rounds here.
//these rounds should start with the last picker and go down by 1 each turn until 1st picker.
int currentVendor = vendors.size()-1; //starts this draft round with the last vendor
while (currentVendor >= 0) {
//this while loop continues running through a single draft round until all vendors get a pick
int currentAppointmentSlot = 0; //looping through the hospital choices for a single vendor
int currentVendorPickSlot=0;
while (currentVendorPickSlot < numOfHospitals) {
//check if hospital and vendor are both open
String currentHospital = vendors.get(currentVendor).vendorPicks[currentVendorPickSlot];
int currentHospitalsIndex = hospitals.indexOf(currentHospital);
if (hospitals.get(currentHospitalsIndex).checkHospitalSchedule(currentAppointmentSlot) != vendors.get(currentVendor).checkVendorSchedule(currentAppointmentSlot)) {
currentAppointmentSlot++;
//continuing the loop if the appointment slot doesn't work
}
else {
vendors.get(currentVendor).setVendorAppointment(currentAppointmentSlot, hospitals.get(currentHospitalsIndex).nameHospital);
hospitals.get(currentHospitalsIndex).setHospitalAppointment(currentAppointmentSlot, vendors.get(currentVendor).salespersonName);
currentVendor++;
break; // does this break the loop?
}
}
currentVendor++;
}
draftRound++;
}
else break;
}
for (int i = 0; i < numOfHospitals; i++) {
System.out.println("Information for hospital #" + i);
System.out.println("Hospital name: " +hospitals.get(i).nameHospital);
System.out.println("Director's name: " + hospitals.get(i).nameDirector);
System.out.println("The hospital's final schedule:");
hospitals.get(i).printHospitalSchedule();
}
for (int i = 0; i < vendors.size(); i++) {
System.out.println("Information for vendor #" + i);
System.out.println("Salesperson's name: "+vendors.get(i).salespersonName);
System.out.println("Company name: " + vendors.get(i).vendorCompanyName);
System.out.println("The vendor's final schedule:");
vendors.get(i).printVendorSchedule();
}
}}
First using stream we will Iterate through hospitals list,
find out the hospital from the list whose name equals currentHospital name, take out the first result using findFirst.
Since the result may be or may not be available it returns Optional.
So on Optional, we will say if it's (the hospital object which we were looking for) present we will get the hospital out of it using the get method
Optional<Hospital> result = hospitals.stream().filter(h -> h.nameHospital.equals(currentHospital)).findFirst();
if(result.isPresent()){
Hospital hospital = result.get();
}

Program will not print the statement

I have a program where i select an option to add ship, which prompts me to give an id e.g b 2. it then prompts me to enter a capacity. However, I am using a search method to prevent any repeat id's that I may enter a second time round. The program compiles, but my statement "Ship id is already in use" won't print out. Any ideas please?
Here is my code.
public int search(String id)
{
for(int index = 0; index < ships.length && ships[index] != null; ++index)
{
shipId = id;
if (ships[index].getId().equals(id))
{
return index;
}
}
//ship id not found so you can add ship
return -1;
}
public void addShip( )
{
System.out.println("Enter ship id >> ");
String id = kb.nextLine();
if(id.equals(search(id)))
{
System.out.println("Ship id already in use");
return;
}
else
{
//for(int i = 0; i < ships.length; ++i)
{
System.out.println("Enter ship capacity");
int capacity = kb.nextInt();
ships[shipCounter++] = new Ship(id, capacity);
}
}
}
Here is my ship class:
public class Ship
{
private String id;
private int capacity;
private int currentCrew; // index into the Crew array
// points to the next free space
// in the Crew array
private String status;
private Crew [ ] crew;
public Ship(String id, int capacity)
{
this.id = id;
this.capacity = capacity;
this.currentCrew = 0;
crew = new Crew[capacity];
}
public Ship(String id, int capacity, String status)
{
this.id = id;
this.capacity = capacity;
this.status = "available";
this.currentCrew = 0;
crew = new Crew[capacity];
}
public void setId(String newId)
{
id = newId;
}
public void setCapacity(int newCapacity)
{
capacity = newCapacity;
}
public void setStatus(String newStatus)
{
if(status.equals("available"))
{
newStatus = "on station";
status = newStatus;
}
else if(status.equals("on station"))
{
newStatus = "maintenance";
status = newStatus;
}
else if(status.equals("station") || status.equals("maintenance"))
{
newStatus = "available";
status = newStatus;
}
else
{
System.out.println("Invalid status");
}
}
public String getId()
{
return id;
}
public String getStatus()
{
return status;
}
public int getCapacity()
{
return capacity;
}
public int getCurrentCrew()
{
return currentCrew;
}
public void addCrew()
{
//if(currentCrew < capacity)
{
//System.out.println("Enter crew id >> ");
//String id = kb.nextLine();
}
}
public String toString()
{
String sdesc =
'\n'
+ "Ship"
+ '\n'
+ "["
+ '\n'
+ " "
+ "Id: " + id
+ " capacity: " + capacity
+ " current crew: " + currentCrew
+ " status: " + status
+ '\n'
+ "]";
return sdesc;
}
}
Did you noticed this line
if(id.equals(search(id)))
id is String type, but search return type is int.
if you see in String class equals method,
if (anObject instanceof String) {
}
return false;
so its simply give false always
so the simple solution is convert that int to String.
something like
if(id.equals(search(id+"")))
If you'd like to see if you already have a ship with the id, you should check that the index exists, which is what your search method returns.
if(search(id) > 0)
{
System.out.println("Ship id already in use");
return;
}

Array not printing out correctly

I've tried moving around my curly braces and just the entire structure of this program a bunch and can't seem to point out how to make this print out correctly. I have a text file that looks like this:
Game of Thrones|Action|HBO|50|Favorite
House of Cards|Drama|Netflix|50|Favorite
Huckabee|Bad Show|Fox News|25|Not favorite
Survivor|Reality|NBC|45|Not favorite
The Daily Show with Jon Stewart|Comedy|Comedy Central|30|Favorite
Louie|Comedy|FX|30|Favorite
Sports Center|Sports News|ESPN|60|Favorite
The Big Bang Theory|Comedy|CBS|30|Not favorite
Sesame Street|Educational|PBS|30|Favorite
Chopped|Food Show|Food Network|60|Favorite
I want my console to show this (minus the pipes) with a toString() that I have, which works perfectly fine, but it prints out with 10 copies of each show and I'm not sure what I can go about doing differently to fix this.
Question: How can I make it so the console prints out exactly 1 copy of each show instead of 10?
Driver Code:
public class TVShowDriver {
public static void main(String[] args) throws FileNotFoundException {
TVShow[] tvShow = new TVShow[10];
String tvName = "";
String genre = "";
String network = "";
int runningTime = 0;
String favorite = "";
// reads in Shows.txt
File tvShows = new File("./src/Shows.txt");
Scanner fileScanner = new Scanner(tvShows);
// while there is a new line in the data, goes to the next one
while (fileScanner.hasNextLine()) {
String line = fileScanner.nextLine();
Scanner lineScanner = new Scanner(line);
lineScanner.useDelimiter("\\|");
// while there is a new attribute to read in on a given line, reads
// data
while (lineScanner.hasNext()) {
tvName = lineScanner.next();
genre = lineScanner.next();
network = lineScanner.next();
runningTime = lineScanner.nextInt();
favorite = lineScanner.next();
// creates a show
for (int i = 0; i < tvShow.length; i++) {
tvShow[i] = new TVShow(tvName, genre, network, runningTime,
favorite);
}
}
// prints out shows
for (int i = 0; i < 10; i++) {
System.out.println(tvShow[i]);
}
}
}
}
TVShow Class:
public class TVShow {
private String tvName;
private String genre;
private String network;
private int runningTime;
private String favorite;
public TVShow(String tvName, String genre, String network, int runningTime, String favorite)
{
this.tvName = tvName;
this.genre = genre;
this.network = network;
this.runningTime = runningTime;
this.favorite = favorite;
}
public String getTvName() {
return tvName;
}
public void setTvName(String tvName) {
this.tvName = tvName;
}
public String getGenre() {
return genre;
}
public void setGenre(String genre) {
this.genre = genre;
}
public String getNetwork() {
return network;
}
public void setNetwork(String network) {
this.network = network;
}
public int getRunningTime() {
return runningTime;
}
public void setRunningTime(int runningTime) {
this.runningTime = runningTime;
}
public String getFavorite() {
return favorite;
}
public void setFavorite(String favorite) {
this.favorite = favorite;
}
public String toString()
{
return "TV Show Name: " + tvName + ", Genre: " + genre + ", Network: " + network + ", Running Time: " + runningTime + " mins" + ", Favorite: " + favorite;
}
}
This...
// creates a show
for (int i = 0; i < tvShow.length; i++) {
tvShow[i] = new TVShow(tvName, genre, network, runningTime,
favorite);
}
...is wrong. Basically, each time you read a line from the file, you are re-filling the array with that show's details (sure you're making a new instance of TVShow, but it contains all the same details.
Instead, use a separate iteration value and increment each time you read a new line...
int currentLine = 0;
while (lineScanner.hasNext()) {
if (currentLine < tvShow.length) {
tvName = lineScanner.next();
genre = lineScanner.next();
network = lineScanner.next();
runningTime = lineScanner.nextInt();
favorite = lineScanner.next();
tvShow[currentLine] = new TVShow(tvName, genre, network, runningTime,
favorite);
currentLine++;
} else {
System.err.println("The array is full");
break;
}
}
I think your problem lies in this piece:
// creates a show
for (int i = 0; i < tvShow.length; i++) {
tvShow[i] = new TVShow(tvName, genre, network, runningTime,favorite);
}
You seem to be filling up the tvShow array each time with ten (which is the length of the array) copies of the same show.
A solution is to have a counter outside of your first while loop which you increment. Then use that counter to index into tvShow.
Alternatively, if you just want to print each show you could not bother to save them all in an array, create a TVShow variable outside of the while loops and reassign it.
So that would look like:
TVShow myShow; // outside of the first while loop loop
myShow = new TVShow(tvName, genre, network, runningTime,favorite); // where you were assigning into the array

Cannot read text file into array and write to text file again

This my whole code.
I want to make a simple program that will read a
text file and put it to array then write it to the
same text file,
also can add and delete the existing input and my input.
Problem
The delete and writer part seems not working, only blank text file when I run the code
These are the error after I select the exit.
java.lang.NullPointerException at ContactList.writer(ContactList.java:51) at
ContactListDriver.main(ContactListDriver.java:73) 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:27‌​2)
public class Contact {
//Each contact stores the name, phone number, and email address
private String name;
private String number;
private String email;
public Contact(String name, String number, String email)
{
this.name = name;
this.number = number;
this.email = email;
}
public String getName()
{
return name;
}
public String getNumber()
{
return number;
}
public String getEmail()
{
return email;
}
public void setName(String name)
{
this.name = name;
}
public void setNumber(String number)
{
this.number = number;
}
public void setEmail(String email)
{
this.email = email;
}
}
class for processing the inputs.
import java.io.*;
import java.lang.*;
import java.util.*;
public class ContactList {
public Contact[] myContacts;
public static final int MAX = 100;
private int numContacts;
public ContactList()
{
myContacts = new Contact[MAX];
numContacts = 0;
}
public void addContact(String name, String number, String email)
{
Contact c = new Contact(name, number, email);
myContacts[numContacts] = c;
numContacts++;
}
public void deleteContact(String name)
{
for ( int i = 0; i <= numContacts-1 ; i++){
if( name == myContacts[i].getName())
{
myContacts[i] = null;
break;
}
}
numContacts--;
}
public void writer(){
String x = "MyContacts.txt";
try {
PrintWriter outputs = new PrintWriter(x);
for( int i=0; i < myContacts.length; i++)
{
Contact c = myContacts[i];
if(c!=null){ // check if c is null before writing to file
outputs.println(""+c.getName()+" "+c.getNumber()+" "+c.getName());
outputs.flush();
}
}
outputs.close();
}catch (IOException e) {
e.printStackTrace();
}
catch(NullPointerException ex){
}
}
public void displayContacts()
{
int i;
for(i=0; i < myContacts.length; i++)
{
Contact c = myContacts[i];
if(null != c){
System.out.println("Name: " + c.getName());
System.out.println("Number: " + c.getNumber());
System.out.println("Email: " + c.getEmail());
System.out.println("------------------------------------");
}
}
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
The Driver....
public class ContactListDriver {
public static void main(String[] args) throws FileNotFoundException
{
ContactList cList = new ContactList();
File in = new File("MyContacts.txt");
Scanner sc = new Scanner(in);
int option;
char again = 'n';
String name = null;
String number = null;
String email = null;
while(sc.hasNext())
{
//read one line from text file
String entry = sc.nextLine();
//System.out.println(entry);
String[] con = entry.split("\\s+");
//System.out.println(con[0] + " " + con[1] + " " + con[2]);
cList.addContact(con[0], con[1], con[2]);
}
Scanner userIn = new Scanner(System.in);
do{
displayOptions();
option = userIn.nextInt();
switch(option)
{
case 1:
System.out.println(" Name > ");
name = userIn.next();
System.out.println(" Number > ");
number = userIn.next();
System.out.println(" Email Address > ");
email = userIn.next();
cList.addContact(name, number, email);
break;
case 2:
//delete contact
System.out.println("Contact Name > ");
name = userIn.next();
cList.deleteContact(name);
break;
case 3:
//display contact
cList.displayContacts();
break;
case 4:
cList.writer();
System.out.println(" are you sure ? press y ");
String x = userIn.next();
again = x.charAt(0);
break;
}
}while( again == 'n' );
}
private static void displayOptions() {
System.out.println("(1) Add");
System.out.println("(2) Delete");
System.out.println("(3) Show Contacts");
System.out.println("(4) Exit");
}
}
One problem I see is:
You have a extra break; statement inside deleteContact(String name) function
and String comparision name == myContacts[i].getName() should be name.equals(myContacts[i].getName())
public void deleteContact(String name)
{
for ( int i = 0; i <= numContacts-1; i++){
if( name.equals( myContacts[i].getName()))// string comparison uses equals();
{
myContacts[i] = null;
numContacts--; // this line should be inside of if condition
break;
}
// break; No need of breaking the loop here
}
}
Another problem is at writer() function
public void writer(){
String x = "MyContacts.txt";
try {
PrintWriter outputs = new PrintWriter(x);
for( int i=0; i < myContacts.length; i++)
{
Contact c = myContacts[i];
if(c!=null){ // check if c is null before writing to file
outputs.println(""+c.getName()+" "+c.getNumber()+" "+c.getName());
outputs.flush();
}
}
outputs.close();
}catch (IOException e) {
e.printStackTrace();
}
catch(NullPointerException ex){ // Or just catch the NPE
}
You have declared and initialized the Contact array of size MAX. but,it seems to be that you haven't initialized the elements though. i.e. c is null in the below code
Contact c = myContacts[i];
outputs.println(""+c.getName()+" "+c.getNumber()+" "+c.getName());
outputs.flush();
myContacts[i] should return a Contact instance. As said by Meno, there are lot of other problems in your code. You have to always cover all the possible scenarios while writing the code.
Most importantly you need to fix the ContactList class. It is inserting new elements into the last index, and deleting at any location using the name.
For example, let's say the ContactList has three elements in it at 0, 1 and 2 indexes. So numContacts is set to 3.
Now ContactList has elements as:
[0]C0, [1]C1, [2]C2, [3]null, ...
Then if the contact at 0 index is deleted (set to null), then numContacts is set to 2.
Now the ContactList has elements as:
[0]null, [1]C1, [2]C2, [3] null, ...
A new insert will be added to the index 2, and it will override the C2 value.
Simplest solution is to use an ArrayList instead of an array.
As others have mentioned there are few more issues to fix, but above is the most important in my opinion.
There are many issues with your code so not easy to say where to begin.
First: Your public void deleteContact(String name)-method is broken. It compares Strings using == instead of equals(). And worse: It creates null pointers mid in your array which will cause problems in your writer()-method.
Second: Why do you use arrays? You should use java.util.ArrayList which offers out-of-the-box implementations for adding, getting and deleting contacts.
Third: If you are missing your text file, you might have overlooked it because of missing path so you don't know where to look for this file. So please add a full path to file name.
Fourth: I would also use scanner.hasNextLine() instead of scanner.hasNext() if you then call scanner.nextLine().
Since you said you are not allowed to use ArrayList you should study its source code especially for removing elements. It does not only nullify the array bucket, but also to shift all following elements one index backwards so you don't have any null gap until the index given by element count. And two breaks in deleteContact()-method are really not necessary.

Infinite while loop in java, not reading in sentinel

I've had this problem throughout multiple programs, but I can't remember how I fixed it last time. In the second while loop in my body, the second sentinel value is never read in for some reason. I've been trying to fix it for a while now, thought I might see if anyone had any clue.
import java.text.DecimalFormat; // imports the decimal format
public class Car {
// Makes three instance variables.
private String make;
private int year;
private double price;
// Makes the an object that formats doubles.
public static DecimalFormat twoDecPl = new DecimalFormat("$0.00");
// Constructor that assigns the instance variables
// to the values that the user made.
public Car(String carMake,int carYear, double carPrice)
{
make = carMake;
year = carYear;
price = carPrice;
}
// Retrieves variable make.
public String getMake()
{
return make;
}
// Retrieves variable year.
public int getYear()
{
return year;
}
// Retrieves variable price.
public double getPrice()
{
return price;
}
// Checks if two objects are equal.
public boolean equals(Car c1, Car c2)
{
boolean b = false;
if(c1.getMake().equals(c2.getMake()) && c1.getPrice() == c2.getPrice() &&
c1.getYear() == c2.getYear())
{
b = true;
return b;
}
else
{
return b;
}
}
// Turns the object into a readable string.
public String toString()
{
return "Description of car:" +
"\n Make : " + make +
"\n Year : " + year +
"\n Price: " + twoDecPl.format(price);
}
}
import java.util.Scanner; // imports a scanner
public class CarSearch {
public static void main(String[] args)
{
// initializes all variables
Scanner scan = new Scanner(System.in);
final int SIZE_ARR = 30;
Car[] carArr = new Car[SIZE_ARR];
final String SENT = "EndDatabase";
String carMake = "";
int carYear = 0;
double carPrice = 0;
int count = 0;
int pos = 0;
final String SECSENT = "EndSearchKeys";
final boolean DEBUG_SW = true;
// Loop that goes through the first list of values.
// It then stores the values in an array, then uses the
// values to make an object.
while(scan.hasNext())
{
if(scan.hasNext())
{
carMake = scan.next();
}
else
{
System.out.println("ERROR - not a String");
System.exit(0);
}
if(carMake.equals(SENT))
{
break;
}
if(scan.hasNextInt())
{
carYear = scan.nextInt();
}
else
{
System.out.println("ERROR - not an int" + count);
System.exit(0);
}
if(scan.hasNextDouble())
{
carPrice = scan.nextDouble();
}
else
{
System.out.println("ERROR - not a double");
System.exit(0);
}
Car car1 = new Car(carMake, carYear, carPrice);
carArr[count] = car1;
count++;
}
// Calls the method debugSwitch to show the debug information.
debugSwitch(carArr, DEBUG_SW, count);
// Calls the method printData to print the database.
printData(carArr, count);
// Loops through the second group of values and stores them in key.
// Then, it searches for a match in the database.
**while(scan.hasNext())**
{
if(scan.hasNext())
{
carMake = scan.next();
}
else
{
System.out.println("ERROR - not a String");
System.exit(0);
}
if(carMake.equals(SECSENT))
{
break;
}
if(scan.hasNextInt())
{
carYear = scan.nextInt();
}
else
{
System.out.println("ERROR - not an int" + count);
System.exit(0);
}
if(scan.hasNextDouble())
{
carPrice = scan.nextDouble();
}
else
{
System.out.println("ERROR - not a double");
System.exit(0);
}
Car key = new Car(carMake, carYear, carPrice);
// Stores the output of seqSearch in pos.
// If the debug switch is on, then it prints these statements.
if(DEBUG_SW == true)
{
System.out.println("Search, make = " + key.getMake());
System.out.println("Search, year = " + key.getYear());
System.out.println("Search, price = " + key.getPrice());
}
System.out.println("key =");
System.out.println(key);
pos = seqSearch(carArr, count, key);
if(pos != -1)
{
System.out.println("This vehicle was found at index = " + pos);
}
else
{
System.out.println("This vehicle was not found in the database.");
}
}
}
// This method prints the database of cars.
private static void printData(Car[] carArr, int count)
{
for(int i = 0; i < count; i++)
{
System.out.println("Description of car:");
System.out.println(carArr[i]);
}
}
// Searches for a match in the database.
private static int seqSearch(Car[] carArr, int count, Car key)
{
for(int i = 0; i < count; i++)
{
boolean b = key.equals(key, carArr[i]);
if(b == true)
{
return i;
}
}
return -1;
}
// Prints debug statements if DEBUG_SW is set to true.
public static void debugSwitch(Car[] carArr, boolean DEBUG_SW, int count)
{
if(DEBUG_SW == true)
{
for(int i = 0; i < count; i++)
{
System.out.println("DB make = " + carArr[i].getMake());
System.out.println("DB year = " + carArr[i].getYear());
System.out.println("DB price = " + carArr[i].getPrice());
}
}
}
}
I think this is your problem, but I might be wrong:
Inside your while loop, you have these calls:
next()
nextInt()
nextDouble()
The problem is that the last call (nextDouble), will not eat the newline. So to fix this issue, you should add an extra nextLine() call at the end of the two loops.
What happens is that the next time you call next(), it will return the newline, instead of the CarMake-thing.

Categories