I have this code and it shown an error: java.lang.NullPointerException at Fastes
ID: 3920908 • Letter: I
Question
I have this code and it shown an error: java.lang.NullPointerException at FastestTrain.main(FastestTrain.java:77)
Please help me fix the error.
The code contains 3 classes:
//FastestTrain Class
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class FastestTrain {
static final String FILE_NAME = "trains.txt";
/**
* This method gets a train list from the file
*
* @throws FileNotFoundException
* - if file not found
*/
static Train[] getTrains() throws FileNotFoundException {
// Scanner to read from the file
Scanner inFile = new Scanner(new File(FILE_NAME));
// Array to hold train details
Train[] trains = null;
// Read file
// Get number of trains
if (inFile.hasNextInt()) {
int numTrains = inFile.nextInt();
// Get distance
if (inFile.hasNextInt()) {
int distance = inFile.nextInt();
// Consume the newline character at the end of distance
inFile.nextLine();
// Array to hold train details
trains = new Train[numTrains];
int count = 0;
// Read train details
while (inFile.hasNextLine()) {
// Get train name
String name = inFile.nextLine().trim();
// Get departure time
String[] depTime = inFile.nextLine().trim().split("\s+");
// Get arrival time
String[] arrTime = inFile.nextLine().trim().split("\s+");
// Add Train to array
trains[count++] = new Train(name,
new Time(Integer.parseInt(depTime[0]), Integer.parseInt(depTime[1])),
new Time(Integer.parseInt(arrTime[0]), Integer.parseInt(arrTime[1])), distance);
}
}
}
// Close scanner
inFile.close();
return trains;
}
public static void main(String[] args) {
try {
// Get train list from file
Train[] trains = getTrains();
// Find fastest train
int index = 0;
Time fastestTime = trains[0].travelTime(trains[0].getArrival());
// System.out.println(trains[0] + " "); // For debugging
for (int i = 1; i < trains.length; i++) {
// Get travel time of train i
Time travelTime = trains[i].travelTime(trains[i].getArrival());
// Check if travel time is less than fastestTime
if ((travelTime.getHour() < fastestTime.getHour()) || ((travelTime.getHour() == fastestTime.getHour())
&& (travelTime.getMinute() < fastestTime.getMinute()))) {
fastestTime = travelTime;
index = i;
}
// System.out.println(trains[i] + " "); // For debugging
}
// Display fastest train
System.out.println("Fastest train as per travel time: " + trains[index]);
} catch (FileNotFoundException fnfe) {
System.out.println("File not found: " + FILE_NAME);
}
}
}
//Time Class
public class Time {
// Instance variables
private Integer hour;
private Integer minute;
/**
* Parameterized constructor
*
* @param hour
* - hour
* @param minute
* - minute
*/
public Time(Integer hour, Integer minute) {
this.hour = hour;
this.minute = minute;
}
/**
* This method returns the hour
*
* @return the hour
*/
public Integer getHour() {
return hour;
}
/**
* This method returns the minute
*
* @return the minute
*/
public Integer getMinute() {
return minute;
}
/**
* This method sets the hour
*
* @param hour
* the hour to set
*/
public void setHour(Integer hour) {
this.hour = hour;
}
/**
* This method sets the minute
*
* @param minute
* the minute to set
*/
public void setMinute(Integer minute) {
this.minute = minute;
}
/**
* This method calculates and returns the time between this time and aTime
*
* @param aTime
* - Time
* @return - time between this time and aTime
*/
public Time timeBetween(Time aTime) {
// Check whether train arrives next day
if ((this.hour > aTime.hour) || ((this.hour == aTime.hour) && (this.minute > aTime.minute))) {
// Get hours remaining for the day to end
int hoursRemaining = 24 - this.hour;
// Subtract this.minute from hoursRemaining
// i.e. get the total minutes remaining for the day to end
int minutesRemaining = (hoursRemaining * 60) - this.minute;
// Calculate minutes elapsed after the next day begins
int minutesElpased = (aTime.hour * 60) + aTime.minute;
// Find sum of minutes
int totalMinutes = minutesRemaining + minutesElpased;
// Return time between this time and aTime
return new Time(totalMinutes / 60, totalMinutes % 60);
} else {
// Get hour difference in minutes
int hourDiffInMin = (aTime.hour - this.hour) * 60;
// Subtract this.minute from hourDiffInMin
hourDiffInMin -= this.minute;
// Add aTime.minute to hourDiffInMin
hourDiffInMin += aTime.minute;
return new Time(hourDiffInMin / 60, hourDiffInMin % 60);
}
}
/**
* This method checks if t is less than zero. If yes then appends t with a
* zero on the left and returns the String, else returns t as a string
*
* @param t
* - integer to be checked
* @return - formatted integer t
*/
public String zeroTime(Integer t) {
if (t < 10)
return "0" + t;
else
return "" + t;
}
@Override
public String toString() {
return zeroTime(hour) + ":" + zeroTime(minute);
}
}
//Train Class
public class Train {
// Instance variables
private String name;
private Time departure;
private Time arrival;
private Integer distance;
/**
* Parameterized constructor
*
* @param name
* - train name
* @param departure
* - departure time of train
* @param arrival
* - arrival time of train at the destination
* @param distance
* - distance from source station to the destination station
*/
public Train(String name, Time departure, Time arrival, Integer distance) {
this.name = name;
this.departure = departure;
this.arrival = arrival;
this.distance = distance;
}
/**
* This method returns the departure time
*
* @return the departure
*/
public Time getDeparture() {
return departure;
}
/**
* This method returns the arrival time
*
* @return the arrival
*/
public Time getArrival() {
return arrival;
}
/**
* This method returns the distance
*
* @return the distance
*/
public Integer getDistance() {
return distance;
}
/**
* This method sets the departure time
*
* @param departure
* the departure to set
*/
public void setDeparture(Time departure) {
this.departure = departure;
}
/**
* This method sets the arrival time
*
* @param arrival
* the arrival to set
*/
public void setArrival(Time arrival) {
this.arrival = arrival;
}
/**
* This method sets the distance
*
* @param distance
* the distance to set
*/
public void setDistance(Integer distance) {
this.distance = distance;
}
/**
* This method finds the average speed of the train
*
* @return - the average speed of the train
*/
public Integer averageSpeed() {
Time travelTime = travelTime(arrival);
return Math.round((distance / (travelTime.getHour() + (travelTime.getMinute() / 60.0f))));
}
/**
* This method finds the time between departure and arrival time
*/
public Time travelTime(Time arrivalTime) {
return departure.timeBetween(arrivalTime);
}
public String toString() {
return name + " " + "Departure " + departure + " " + "Arrival " + arrival + " " + "Travel Time "
+ travelTime(arrival) + " " + "Average speed " + averageSpeed() + " km/h";
}
}
The txt file is:
650
10
Night Express
23 55
8 15
Red Arrow
22 10
7 45
Star
10 30
19 25
Comfort
11 45
20 40
Budget
5 50
18 55
Day Rocket
11 55
16 00
Super Star
12 20
16 48
Good Morning
21 20
8 45
Best Choice
20 00
7 25
Sunrise
21 30
5 40
Explanation / Answer
Hello there, the problem is with your data file. Or the way in which you read the data file. In the data file ‘trains.txt’, first line is 650, which is the total distance. And the next line is the number of trains. But when you read the data (getTrains() method of FastestTrain class), you read first line as the number of trains, and the next line as the total distance. Therefore, program thinks that there are 650 trains, and try to read more ‘trains info’ than what actually the trains.txt has. Therefore, a simple way to make your program run without error is to swap the first two lines of trains.txt. Make first line 10 and next line 650.
If you do not want to make changes to data file, then make changes in the getTrains() method, read distance first, and then read numTrains.
You have to do only one of the above 2 suggestions, then your program won’t run into NullPointerException
My output
Fastest train as per travel time:
Day Rocket
Departure 11:55
Arrival 16:00
Travel Time 04:05
Average speed 159 km/h
If you have any queries, just drop a comment. Thanks.
If you do not want to change data file, then use the below code for FastestTrain class.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class FastestTrain {
static final String FILE_NAME = "trains.txt";
/**
* This method gets a train list from the file
*
* @throws FileNotFoundException
* - if file not found
*/
static Train[] getTrains() throws FileNotFoundException {
// Scanner to read from the file
Scanner inFile = new Scanner(new File(FILE_NAME));
// Array to hold train details
Train[] trains = null;
// Read file
// Get distance
if (inFile.hasNextInt()) {
int distance = inFile.nextInt();
// Get number of trains
if (inFile.hasNextInt()) {
int numTrains = inFile.nextInt();
// Consume the newline character at the end of distance
inFile.nextLine();
// Array to hold train details
trains = new Train[numTrains];
int count = 0;
// Read train details
while (inFile.hasNextLine()) {
// Get train name
String name = inFile.nextLine().trim();
// Get departure time
String[] depTime = inFile.nextLine().trim().split("\s+");
// Get arrival time
String[] arrTime = inFile.nextLine().trim().split("\s+");
// Add Train to array
trains[count++] = new Train(name, new Time(
Integer.parseInt(depTime[0]),
Integer.parseInt(depTime[1])), new Time(
Integer.parseInt(arrTime[0]),
Integer.parseInt(arrTime[1])), distance);
}
}
}
// Close scanner
inFile.close();
return trains;
}
public static void main(String[] args) {
try {
// Get train list from file
Train[] trains = getTrains();
// Find fastest train
int index = 0;
Time fastestTime = trains[0].travelTime(trains[0].getArrival());
// System.out.println(trains[0] + " "); // For debugging
for (int i = 1; i < trains.length; i++) {
// Get travel time of train i
Time travelTime = trains[i].travelTime(trains[i].getArrival());
// Check if travel time is less than fastestTime
if ((travelTime.getHour() < fastestTime.getHour())
|| ((travelTime.getHour() == fastestTime.getHour()) && (travelTime
.getMinute() < fastestTime.getMinute()))) {
fastestTime = travelTime;
index = i;
}
// System.out.println(trains[i] + " "); // For debugging
}
// Display fastest train
System.out.println("Fastest train as per travel time: "
+ trains[index]);
} catch (FileNotFoundException fnfe) {
System.out.println("File not found: " + FILE_NAME);
}
}
}