Ned help with this: Exception in thread "main" java.util.NoSuchElementException
My code is a payroll program that keeps track of an employee's first and last names, salary, and address. Whenever I try to run the program, I get the following error message:
Exception in thread "main" java.util.NoSuchElementException
at java.util.StringTokenizer.nextToken(StringTokenize r.java:349)
at Payroll.<init>(Payroll.java:26)
at PayrollTest.main(PayrollTest.java:16)
Going off of this, I can assume that the problem lies with my String Tokenizer, but I can't seem to figure out exactly why. I think it might be because of the fact that the String Tokenizer reads from a file and that since the last line doesn't have anything on it it seems to be trying to read it and get a token from it, thus giving me an error. If anyone can point me in the right direction then it would be greatly appreciated. On a sidenote, does anyone know how to edit a post to say SOLVED by it? I ended up solving my own problem under the "Help me with my code" forum on this site and can't seem to figure out how to change it to SOLVED.
Code java:
import java.util.*;
import java.io.*;
public class PayrollTest {
public static void main(String[] args)throws IOException
{
Payroll Employee1 = new Payroll("payrollSample.txt");
Scanner keyboard = new Scanner(System.in);
System.out.println("Please choose a function below."
+ "\n\na - add new "
+ "employee\nr - remove employee from the address book\nf - "
+ "find an employee's information\np - print out payroll\nq "
+ "- quit program");
String input = keyboard.nextLine();
if (input.equals("a"))
addEmployee();
}
public static void addEmployee(){
Scanner keyboard = new Scanner(System.in);
System.out.println("What is the employee's first name?");
String firstName = keyboard.nextLine();
System.out.println("What is the employee's last name?");
String lastName = keyboard.nextLine();
System.out.println("What is the employee's salary?");
double salary = keyboard.nextDouble();
System.out.println("What is the employee's address?");
String address = keyboard.nextLine();
boolean success = Employee1.add(firstName, lastName, salary, address);
if (success == true)
System.out.println("The employee has been added.");
else
System.out.println("The employee is already in the system.");
}
}
Code java:
import java.util.*;
import java.io.*;
public class Payroll {
private ArrayList<Employee> payList;
public Payroll(){
payList = new ArrayList<Employee>();
}
public Payroll(String filename)throws IOException{
payList = new ArrayList<Employee>();
Scanner fileInput = new Scanner(new File(filename));
while (fileInput.hasNextLine()){
String line = fileInput.nextLine();
StringTokenizer st = new StringTokenizer(line, "~");
String firstName = st.nextToken();
String lastName = st.nextToken();
double salary = Double.parseDouble(st.nextToken());
String address = st.nextToken();
payList.add(new Employee(firstName, lastName, salary, address));
}
}
private int search(String firstName, String lastName){
int i = 0;
Employee tempEmployee = new Employee(firstName, lastName, 0.0, null);
for (i = 0; i < payList.size(); i++){
if (payList.get(i).equals(tempEmployee))
return i;
}
return -1;
}
public boolean add(String firstName, String lastName, double salary,
String address){
int index = search(firstName, lastName);
if (index == -1){
payList.add(new Employee(firstName, lastName, salary, address));
return true;
}
else
return false;
}
public boolean remove(String firstName, String lastName){
int index = search(firstName, lastName);
if (index == -1)
return false;
return true;
}
public String findAllInfo(String firstName, String lastName){
int index = search(firstName, lastName);
if (index == -1)
System.out.println("The Employee you requested does not work here");
return payList.get(index).toString();
}
public void printPayRoll(){
int i = 0;
for (i = 0; i < payList.size(); i++){
System.out.println(payList.get(i));
}
}
}
Code java:
public class Employee {
static int empcount = 0;
private int empID = 0;
private String firstName = null;
private String lastName = null;
private String address = null;
private double salary = 0.0;
public Employee(){
}
public Employee(String fname, String lname, double sal, String addr){
firstName = fname;
lastName = lname;
address = addr;
salary = sal;
}
public int getID(){
return empID;
}
public String getFirstName(){
return firstName;
}
public String getLastName(){
return lastName;
}
public String getAddress(){
return address;
}
public double getSalary(){
return salary;
}
public void setFirstName(String fname){
firstName = fname;
}
public void setLastName(String lname){
lastName = lname;
}
public void setAddress(String addr){
address = addr;
}
public String toString(){
return firstName + "~" + lastName + "~" + salary + "~" + address;
}
public boolean equals (Object obj){
return false;
}
}
Re: Ned help with this: Exception in thread "main" java.util.NoSuchElementException
Please indicate with an obvious comment which line in the code above is causing this exception to be thrown. By obvious comment, I mean something like // **** the error is here ****.
Re: Ned help with this: Exception in thread "main" java.util.NoSuchElementException
I see potential for problems here:
Code :
System.out.println("What is the employee's last name?");
String lastName = keyboard.nextLine();
System.out.println("What is the employee's salary?");
double salary = keyboard.nextDouble();
System.out.println("What is the employee's address?");
String address = keyboard.nextLine();
You are getting a double value with Scanner's nextDouble() method but not handling the end of line token, and this can make the Scanner get the nextLine() premature to what you expect. Consider changing the above code to:
Code :
System.out.println("What is the employee's last name?");
String lastName = keyboard.nextLine();
System.out.println("What is the employee's salary?");
double salary = keyboard.nextDouble();
keyboard.nextLine(); // **** add this ****
System.out.println("What is the employee's address?");
String address = keyboard.nextLine();
So that the Scanner handles the end of line token after getting the double value.
Re: Ned help with this: Exception in thread "main" java.util.NoSuchElementException
Sorry about that. I changed my code to your suggestion but it didn't solve the problem. I'll repost with the comment where the problem is.
Code java:
import java.util.*;
import java.io.*;
public class Payroll {
private ArrayList<Employee> payList;
public Payroll(){
payList = new ArrayList<Employee>();
}
public Payroll(String filename)throws IOException{
payList = new ArrayList<Employee>();
Scanner fileInput = new Scanner(new File(filename));
while (fileInput.hasNextLine()){
String line = fileInput.nextLine();
StringTokenizer st = new StringTokenizer(line, "~");
String firstName = st.nextToken(); //****This is where the problem is****//
String lastName = st.nextToken();
double salary = Double.parseDouble(st.nextToken());
String address = st.nextToken();
payList.add(new Employee(firstName, lastName, salary, address));
}
}
private int search(String firstName, String lastName){
int i = 0;
Employee tempEmployee = new Employee(firstName, lastName, 0.0, null);
for (i = 0; i < payList.size(); i++){
if (payList.get(i).equals(tempEmployee))
return i;
}
return -1;
}
public boolean add(String firstName, String lastName, double salary,
String address){
int index = search(firstName, lastName);
if (index == -1){
payList.add(new Employee(firstName, lastName, salary, address));
return true;
}
else
return false;
}
public boolean remove(String firstName, String lastName){
int index = search(firstName, lastName);
if (index == -1)
return false;
return true;
}
public String findAllInfo(String firstName, String lastName){
int index = search(firstName, lastName);
if (index == -1)
System.out.println("The Employee you requested does not work here");
return payList.get(index).toString();
}
public void printPayRoll(){
int i = 0;
for (i = 0; i < payList.size(); i++){
System.out.println(payList.get(i));
}
}
}
Re: Ned help with this: Exception in thread "main" java.util.NoSuchElementException
Thanks for the updated information! Now for more questions: Do you have any empty lines in your text file? Do you check for that before trying to extract tokens? Have you tried to debug your code? For example:
Code :
while (fileInput.hasNextLine()){
String line = fileInput.nextLine();
System.out.println("line: " + line); // *** added a debug line
StringTokenizer st = new StringTokenizer(line, "~");
String firstName = st.nextToken();
Then run the program to see which line of text your code chokes on.
Re: Ned help with this: Exception in thread "main" java.util.NoSuchElementException
Alright, so it seems that its counting the empty line at the end of the file as a line and trying to read it. Below is the contents of the .txt file:
Code :
Douglas~Waldron~49000.00~City Hall, 9027 Center Street, Manassas, VA 20110
Robert~Marshall~87233.00~PO Box 421, Manassas, VA 20108
Charles~Colgan~102899.00~10677 Aviation Lane, Manassas, VA 20110-2701
Bill~Bolling~67222.00~P0 Box 396, Richmond, VA 23218
Tim~Kaine~56111.00~Patrick Henry Building, 3rd Floor, 1111 East Broad Street, Richmond, VA 23219
Jim~Webb~88000.00~507 East Franklin Street, Richmond, VA 23219
John~Warner~120050.00~225 Russell Building, Washington, DC 20510
Now, this is the new error message I'm getting:
Code :
line: Douglas~Waldron~49000.00~City Hall, 9027 Center Street, Manassas, VA 20110
line: Robert~Marshall~87233.00~PO Box 421, Manassas, VA 20108
line: Charles~Colgan~102899.00~10677 Aviation Lane, Manassas, VA 20110-2701
line: Bill~Bolling~67222.00~P0 Box 396, Richmond, VA 23218
Exception in thread "main" java.util.NoSuchElementException //****This is a problem****//
line: Tim~Kaine~56111.00~Patrick Henry Building, 3rd Floor, 1111 East Broad Street, Richmond, VA 23219
line: Jim~Webb~88000.00~507 East Franklin Street, Richmond, VA 23219
line: John~Warner~120050.00~225 Russell Building, Washington, DC 20510
line: //****This is a problem****//
at java.util.StringTokenizer.nextToken(StringTokenizer.java:349)
at Payroll.<init>(Payroll.java:27)
at PayrollTest.main(PayrollTest.java:16)
I'm not sure why the exception is in the middle of the data as opposed to the blank line at the end.
Re: Ned help with this: Exception in thread "main" java.util.NoSuchElementException
Myself, I'd use String#split("~") for what you're doing, which would return an array of tokens, and then I'd check the length of this array before processing it.
Can you post your output without the comment. Is the exception occurring before or after the line you've indicated?
Re: Ned help with this: Exception in thread "main" java.util.NoSuchElementException
So I commented out the String Tokenizer and tried the split option, but now it gives me an entirely new error:
Code :
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at Payroll.<init>(Payroll.java:34)
at PayrollTest.main(PayrollTest.java:16)
Here is my revised code:
Code java:
import java.io.*;
import java.util.*;
public class Payroll {
private ArrayList<Employee> payList;
public Payroll(){
payList = new ArrayList<>();
}
public Payroll(String filename)throws IOException{
payList = new ArrayList<>();
Scanner fileInput = new Scanner(new File(filename));
while (fileInput.hasNextLine()){
String line = fileInput.nextLine();
/*System.out.println("line: " + line);
StringTokenizer st = new StringTokenizer(line, "~");
String firstName = st.nextToken();
String lastName = st.nextToken();
double salary = Double.parseDouble(st.nextToken());
String address = st.nextToken();*/
String[] tokens = line.split("~");
String firstName = tokens[0];
String lastName = tokens[1]; //****This is the problem line.****//
double salary = Double.parseDouble(tokens[2]);
String address = tokens[3];
payList.add(new Employee(firstName, lastName, salary, address));
}
}
private int search(String firstName, String lastName){
int i;
Employee tempEmployee = new Employee(firstName, lastName, 0.0, null);
for (i = 0; i < payList.size(); i++){
if (payList.get(i).equals(tempEmployee)) {
return i;
}
}
return -1;
}
public boolean add(String firstName, String lastName, double salary,
String address){
int index = search(firstName, lastName);
if (index == -1){
payList.add(new Employee(firstName, lastName, salary, address));
return true;
}
else {
return false;
}
}
public boolean remove(String firstName, String lastName){
int index = search(firstName, lastName);
if (index == -1) {
return false;
}
return true;
}
public String findAllInfo(String firstName, String lastName){
int index = search(firstName, lastName);
if (index == -1) {
System.out.println("The Employee you requested does not work here");
}
return payList.get(index).toString();
}
public void printPayRoll(){
int i;
for (i = 0; i < payList.size(); i++){
System.out.println(payList.get(i));
}
}
}
Re: Ned help with this: Exception in thread "main" java.util.NoSuchElementException
When the going gets tough, the tough do some more debugging. Consider printing out each token to see what the split results in. You're somehow reading in a short line in there somewhere.
Re: Ned help with this: Exception in thread "main" java.util.NoSuchElementException
Curmudgeon, you are an awesome person. I wish I could thank you more than I already have. I just rewrote the file that my teacher gave us and saved it as the same thing, and now the program works like a dream. Its amazing that it was so simple, but I really appreciate you giving your time to help me, and I actually learned quite a few new things from you as well, so thanks for that. By the way, you wouldn't happen to know how to mark this topic as SOLVED would you? I can't figure it out.
Re: Ned help with this: Exception in thread "main" java.util.NoSuchElementException
Quote:
Originally Posted by
bankston13
... By the way, you wouldn't happen to know how to mark this topic as SOLVED would you? I can't figure it out.
Near the top of the page under Thread Tools.
Re: Ned help with this: Exception in thread "main" java.util.NoSuchElementException
Quote:
Originally Posted by
bankston13
Curmudgeon, you are an awesome person. I wish I could thank you more than I already have. I just rewrote the file that my teacher gave us and saved it as the same thing, and now the program works like a dream. Its amazing that it was so simple, but I really appreciate you giving your time to help me, and I actually learned quite a few new things from you as well, so thanks for that. By the way, you wouldn't happen to know how to mark this topic as SOLVED would you? I can't figure it out.
You're welcome, and glad you've got things working now. You seem to be able to grasp things quickly and willing to experiment, so I predict much success with you and your Java coding education. Best of luck!