I'm new to programming and I keep making the mistake of having a method do too much work. My TA gave me some advice that I should aim to make a method reusable enough that I can use it in another program without having to really modify very much. This definitely helped me approach writing methods in a better way, but I'm worried that I might have made my "add" method too meaty. Should I split it up or is it technically doing "one thing" even though it's pretty chunky?
Here's my main class (the referenced classes are just basic templates that don't do anything special aside from having getters and setters so I won't bother posting them here):
import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.Scanner;
enum ClassStanding{FRESHMAN,SOPHOMORE,JUNIOR,SENIOR,UNKNOWN,MASTERS_STUDIES,PHD_STUDIES};
enum Major{CS,CEG,EE,ISE,BME,ME,MET,UNKNOWN};
enum StudentType{UNDERGRADUATE,GRADUATE,UNDECLARED};
public class Main {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Scanner stdin = new Scanner(System.in);
ArrayList<Student> studentList = new ArrayList<>();
int counter;
boolean continueInput;
int contCounter;
do {
do {
System.out.print("Please enter what you want to do-ADD, REMOVE, LIST, or SAVE: ");
switch (stdin.next().toLowerCase()) {
case "add": add(stdin, studentList); counter = 0; break;
case "remove": counter = 0; break;
case "list": counter = 0; break;
case "save": counter = 0; break;
default: System.out.println("Improper input, please enter only ADD, REMOVE, LIST, or SAVE."); counter = 1;
}
} while (counter == 1);
do {
System.out.print("\nDo you want to continue? Yes or no: ");
switch (stdin.next().toLowerCase()) {
case "yes": contCounter = 0; continueInput = true; break;
case "no": contCounter = 0; continueInput = false; break;
default: contCounter = 1; continueInput = false; System.out.print("\nPlease only enter 'yes' or 'no'.");
}
} while (contCounter == 1);
} while (continueInput);
} // end main method
public static void add(Scanner stdin, ArrayList<Student> studentList) { // this is the one
String firstName;
String lastName;
String uid;
StudentType studentType;
ClassStanding studentClassStanding;
Major major;
double overallGPA;
double majorGPA;
String majorProfessor;
boolean thesisOption;
System.out.print("Please enter the student's first name: ");
String tempName = stdin.next();
firstName = checkName(tempName);
System.out.print("Please enter the student's last name: ");
tempName = stdin.next();
lastName = checkName(tempName);
System.out.println("Please enter the student's UID in the format 'U####' or 'U#####': ");
String tempUID = stdin.next();
uid = checkUID(tempUID).toUpperCase();
int count;
do {
System.out.print("Please enter the student's status as UNDECLARED, UNDERGRADUATE, or GRADUATE: ");
switch (stdin.next().toUpperCase()) {
case "UNDECLARED":
studentType = StudentType.UNDECLARED;
studentClassStanding = setStudentClassStanding(studentType);
count = 0;
Student student = new Student(firstName, lastName,
uid, studentType, studentClassStanding);
studentList.add(student);
break;
case "UNDERGRADUATE":
studentType = StudentType.UNDERGRADUATE;
major = setMajor();
studentClassStanding = setStudentClassStanding(studentType);
System.out.println("Enter the student's overall GPA below.");
overallGPA = setGPA();
System.out.println("Enter the student's major GPA below.");
majorGPA = setGPA();
count = 0;
UnderGraduate underGraduate = new UnderGraduate(firstName, lastName, uid, studentType,
studentClassStanding, major, overallGPA, majorGPA);
studentList.add(underGraduate);
break;
case "GRADUATE":
studentType = StudentType.GRADUATE;
studentClassStanding = setStudentClassStanding(studentType);
majorProfessor = setMajorProfessor();
thesisOption = setThesisOption();
count = 0;
Graduate graduate = new Graduate(firstName, lastName, uid, studentType,
studentClassStanding, majorProfessor, thesisOption);
studentList.add(graduate);
break;
default:
System.out.println("Please enter either Undeclared, Undergraduate, or Graduate only.");
count = 1;
}
} while (count == 1);
}
public static String checkName(String tempName) {
int a = 1;
String name1;
Scanner scanner = new Scanner(System.in);
do {
name1 = tempName; // hold the value of firstName in name1
for (int i = 0; i < tempName.length(); i++) { // loop to check input consists of letters (is a name)
if (!Character.isLetter(tempName.charAt(i))) { // if non-letters detected, ensure this was intentional
System.out.println("Please ensure you've entered the correct name. Re-enter the name or enter 'continue' to proceed: ");
tempName = scanner.nextLine();
if (tempName.equalsIgnoreCase("continue")) { // if user enters "continue", use original input
a = 0;
tempName = name1; // pass name1 value to firstName
break;
} else {
a = 1; // continue prompting for firstName
}
} else { // accept input
a = 0;
}
}
} while (a == 1); // loop to ensure proper input
return tempName;
} // end checkName method
public static String checkUID(String tempUID) {
Scanner scan = new Scanner(System.in);
int a;
do {
if (tempUID.charAt(0) == 'U' || tempUID.charAt(0) == 'u') {
if (tempUID.length() == 6 || tempUID.length() == 5) {
a = 0;
} else {
a = 1;
System.out.print("Please ensure input is in the form of U#### or U#####. Please re-enter the UID: ");
tempUID = scan.next();
}
} else {
a = 1;
System.out.print("Please ensure input is in the form of U#### or U#####. Please re-enter the UID: ");
tempUID = scan.next();
}
} while (a == 1);
return tempUID;
} // end checkUID method
public static ClassStanding setStudentClassStanding(StudentType studentType) {
Scanner scan = new Scanner(System.in);
int count;
ClassStanding studentTempClassStanding = null;
do {
if (studentType == StudentType.UNDECLARED || studentType == StudentType.UNDERGRADUATE) {
System.out.print("Please enter the student's class standing as either Freshman, Sophomore, Junior, Senior, or Unknown: ");
switch (scan.next().toUpperCase()) {
case "FRESHMAN":
studentTempClassStanding = ClassStanding.FRESHMAN;
count = 0;
break;
case "SOPHOMORE":
studentTempClassStanding = ClassStanding.SOPHOMORE;
count = 0;
break;
case "JUNIOR":
studentTempClassStanding = ClassStanding.JUNIOR;
count = 0;
break;
case "SENIOR":
studentTempClassStanding = ClassStanding.SENIOR;
count = 0;
break;
case "UNKNOWN":
studentTempClassStanding = ClassStanding.UNKNOWN;
count = 0;
break;
default:
System.out.println("Please enter only Freshman, Sophomore, Junior, Senior, or Unknown.");
count = 1;
}
} else {
System.out.print("Please enter the student's class standing as either 'Masters' for Masters Studies or 'PhD' for PhD Studies: ");
switch (scan.next().toUpperCase()) {
case "MASTERS": studentTempClassStanding = ClassStanding.MASTERS_STUDIES; count = 0; break;
case "PHD": studentTempClassStanding = ClassStanding.PHD_STUDIES; count = 0; break;
default: System.out.println("Please enter only 'Masters' or 'PhD'.");
count = 1;
}
}
} while (count == 1);
return studentTempClassStanding;
} // end setStudentClassStanding method
public static Major setMajor() {
Major tempMaj = null;
Scanner s = new Scanner(System.in);
int c;
do {
System.out.print("Please enter the student's major as either CS, CEG, EE, ISE, BME, ME, MET, or Unknown: ");
switch (s.next().toUpperCase()) {
case "CS":
tempMaj = Major.CS;
c = 0;
break;
case "CEG":
tempMaj = Major.CEG;
c = 0;
break;
case "EE":
tempMaj = Major.EE;
c = 0;
break;
case "ISE":
tempMaj = Major.ISE;
c = 0;
break;
case "BME":
tempMaj = Major.BME;
c = 0;
break;
case "ME":
tempMaj = Major.ME;
c = 0;
break;
case "MET":
tempMaj = Major.MET;
c = 0;
break;
case "UNKOWN":
tempMaj = Major.UNKNOWN;
c = 0;
break;
default:
System.out.println("Please enter only the specified values. ");
c = 1;
}
} while (c == 1);
return tempMaj;
} // end setMajor method
public static double setGPA() {
Scanner s = new Scanner(System.in);
double gpa;
int a;
do {
try {
System.out.print("Please enter the student's GPA: ");
gpa = s.nextDouble();// read in the gpa
if (gpa < 0.0 || gpa > 4.0) { // ensure the gpa is in the correct range
System.out.println("Invalid input, please enter a positive value between 0.0 and 4.0.");
a = 1;
} else {
a = 0;
}
} catch (InputMismatchException ex) { //catch any exceptions, prompt for correct input
a = 1;
gpa = 0.0;
System.out.println("Sorry, please enter a double value.");
s.nextLine(); // skip the last input
}
} while (a == 1 || gpa < 0.0 || gpa > 4.0); //loop while gpa is negative or incorrect input is received
return gpa;
} // end setGPA method
private static String setMajorProfessor() {
Scanner s = new Scanner(System.in);
String prof;
System.out.print("Please enter the name of the major professor: ");
String tempName = s.nextLine();
prof = checkName(tempName);
return prof;
} // end setMajorProfessor method
private static boolean setThesisOption() {
Scanner s = new Scanner(System.in);
boolean thesis = false;
int a;
do {
System.out.print("Please enter 'yes' if a thesis will be written, otherwise enter 'no': ");
switch (s.next().toUpperCase()) {
case "YES": thesis = true; a = 0; break;
case "NO": thesis = false; a = 0; break;
default: System.out.println("Please enter only 'yes' or 'no'."); a = 1;
}
} while (a == 1);
return thesis;
} // end setThesisOption method
}
The focus of this project is to have a menu of options for the user (add, list, save, sort, remove) that will allow them perform a series of operations on an arraylist they supply (through the add function). Obviously I'm not done and I'm not looking for help on my project, I'm just wondering if I made my "add" method too meaty. I tried to break it up as best I could by calling other methods to do a lot of the work in it, but I still feel like it might be too much work for the method. But then again it could be fine, I really don't know-I haven't yet gotten a feel for how much a method should really do.
Yes, this definitely does too much.
In software design, people have introduced what they call bad smells, GRASP patterns and design patterns to give more scientific arguments to a discussion.
Bad smells: also called antipatterns. They include for instance god class (a class that does everything), seems very applicable here. These are alarms that you should refactor your code.
GRASP patterns: these are more or less the directions in which your code should move. Two applicable here are controller and low coupeling: split I/O and data manipulation from each other and definitely make sure that most methods don't need data provided/stored by other methods/classes.
Design patterns: these are a set of patterns one can apply to achieve the GRASP patterns. For instance you can use a Factory to built new instances, or use a Chain of Responsiblity to split a problem into small subproblems that are handled separately.
Some final advices by quotes:
"Two or more, use a for" - E. W. Dijkstra
"A method should in most circumstances not contain more than 15 lines" - Some of my teachers
There are some rules and there are some tools to help with those rules. Basically using a static code analyzer helps to determine whether the method is too big or doing too many things. Findbugs is one of the famous static code analyzer.
Related
Building a basic bank account with Java using methods. I am creating a new method to withdraw from the bank account. This is the code that I came up with right now, but on netbeans it shows that there are errors.
I created a new method called withDrawal. This code below is for the withdrawing from account and to not let the balance in the account go below zero!
private static void withDrawal()
{
int accountIndex = findAccount();
int verifyPin = checkPin (!=0);
if(accountIndex != -1)
if(verifyPin !=-2)
{
accounts[accountIndex].withDrawal();
accounts[verifyPin].checkPin();
int withDra = input.nextInt();
}
else
{
System.out.println("Account does not exist!");
System.out.printf("Enter amount you want to withdraw: ");
}
}
Java file
package grossmontbank;
import java.util.Scanner;
public class GrossmontBank
{
//class variables (global - accessible throughout this class)
//scanner object to be used throughout
private static Scanner input = new Scanner(System.in);
//array of blank accounts
private static final int MAX_ACCOUNTS = 50;
private static Account[] accounts = new Account[MAX_ACCOUNTS];
//total accounts created
private static int totalAccounts = 0;
//main class mimics a bank teller
public static void main(String[] args)
{
char choice;
//loop until 'Q' is entered
do
{
choice = getChoice(); //getChoice() will only return with a C, B, W, D or Q
if(choice != 'Q')
{
switch(choice)
{
case 'C': createAccount();
break;
case 'B': checkBalance();
break;
case 'W':
break;
case 'D':
break;
}
}
}while(choice != 'Q');
closeBank(); //outputs all account holders and 'closes' the bank
}
/*method checkBalance calls method findAccount()
* if account exists, calls Account method checkBalance()
*/
private static void checkBalance()
{
int accountIndex = findAccount();
//findAccount() returns index of account if found, -1 if not found
if(accountIndex != -1)
{
accounts[accountIndex].checkBalance();
}
else
{
System.out.println("Account does not exist");
}
}
/*method checkIfExists determines if account holder already exists
* returns true if account holder exists, false otherwise
*/
private static boolean checkIfExists(String firstName, String lastName)
{
//loops through account array to see if account name already exists
for(int i = 0; i < totalAccounts;i++)
{
//compares the names, ignoring upper/lower
if(accounts[i].getFirstName().equalsIgnoreCase(firstName)
&& accounts[i].getLastName().equalsIgnoreCase(lastName))
{
System.out.println("Account holder already exists. Please verify and re-enter. ");
return true;
}
}
return false;
}
/*method closeBank prints out closing statement
* prints out list of all account holders
*/
private static void closeBank()
{
System.out.println("Closing the follow accounts:");
for(int i = 0; i < totalAccounts;i++)
{
//printing an account object invokes the Account class method toString()
//prints first and last name only
System.out.printf(" %s%n",accounts[i]);
}
System.out.println("Grossmont Bank is officially closed.");
}
/*method createAccount creates a single bank account
* checks to ensure account holder does not already exist
* returns Account object
*/
private static void createAccount()
{
String first, last, initial;
boolean exists = false;
//only create a new account if MAX_ACCOUNTS has not been reached
if(totalAccounts < MAX_ACCOUNTS )
{
//loop until a new account name has been entered
do
{
System.out.print("Enter your first name: ");
first = input.next();
System.out.print("Enter your last name: ");
last = input.next();
exists = checkIfExists(first,last);
}while(exists == true);
System.out.print("Will you be making an initial deposit? Enter Yes or No: ");
initial = input.next();
//if no initial deposit, call 2 parameter constructor, otherwise call 3 param one
if(initial.equals("No"))
{
accounts[totalAccounts] = new Account(first,last);
}
else
{
System.out.print("Enter initial deposit amount: ");
accounts[totalAccounts] = new Account(first,last, input.nextDouble());
}
//increment totalAccounts created (used throughout program)
totalAccounts++;
}
else
{
System.out.println("Maximum number of accounts has been reached. ");
}
}
/*method findAccount asks for first and last name
* searchs for account holder in array
* if exists, returns array index of this account
* if doesn't exist, returns '-1'
* called from checkBalance()
*/
private static int findAccount()
{
String first, last;
System.out.print("Enter first name: ");
first = input.next();
System.out.print("Enter last name: ");
last = input.next();
//loops through account array
for(int i = 0; i < totalAccounts;i++)
{
//compares the names, ignoring upper/lower
if(accounts[i].getFirstName().equalsIgnoreCase(first)
&& accounts[i].getLastName().equalsIgnoreCase(last))
{
return i; //returns the index of the account
}
}
return -1; //if account not found
}
/* method getChoice() outputs options
* inputs choice from user and validates
* returns choice char
*/
private static char getChoice()
{
char choice;
//output menu options
System.out.println();
System.out.println("Welcome to Grossmont Bank. Choose from the following options: ");
System.out.println(" C - create new account");
System.out.println(" B - check your balance");
System.out.println(" D - deposit");
System.out.println(" W - withdrawal");
System.out.println(" Q - quit");
//loop until a valid input is entered
do
{
System.out.print("Enter choice: ");
choice = input.next().charAt(0);
//if choice is one of the options, return it. Otherwise keep looping
if(choice == 'C' || choice == 'B' || choice == 'D' || choice == 'W' || choice == 'Q')
return choice;
else
{
System.out.println("Invalid choice. Ensure a capital letter. Please re-enter.");
choice = '?';
}
}while(choice == '?');
return choice; //will never get here, but required to have a return statement to compile
}
private static void withDrawal()
{
int accountIndex = findAccount();
int verifyPin = checkPin (!=0);
if(accountIndex != -1)
if(verifyPin !=-2)
{
accounts[accountIndex].withDrawal();
accounts[verifyPin].checkPin();
int withDra = input.nextInt();
}
else
{
System.out.println("Account does not exist!");
System.out.printf("Enter amount you want to withdraw: ");
}
}
}
I'm just learning Java and trying to make a simple phone book. For this part I'm trying to prompt the user to choose one of the 3 options below.
public class PhoneBook {
public static void main (String[] args){
options();
/*This method prompts the user to enter phone number
String s;
Scanner in = new Scanner(System.in);
System.out.println("Enter Phone Number");
s = in.nextLine();
System.out.println("You entered phone number ");
System.out.println(s);*/
}
public static void options (){
//This method gives the user choices on what to do
char choice;
char enterNumber = 'n';
char showNumber = 's';
char closeBook = 'c';
String read;
String freeLine = "error";
Scanner keyboard = new Scanner(System.in);
while (true){
System.out.println("Please select from the following");
System.out.println("n to Enter the number");
System.out.println("s to Show the number ");
System.out.println("c to Close the Phone book");
read = keyboard.nextLine();
choice = read.charAt(0);
switch (choice) {
case 'n': enterNumber;
system.out.println();
case 's':showNumber;
system.out.println();
case 'c': closeBook;
break;
default: System.out.println("Invalid Entry");
}
}
}
}
When I compile it i get errors on lines 37, 39, and 41 saying "Error: not a statement". I feel like something is missing. If anyone can help it would be greatly appreciated.
I am assuming that with the following lines you want to achieve to print the letter n for enterNumber in the console?
case 'n': enterNumber;
system.out.println();
This is not correct Java syntax. You will have to pass the variable value to the System.out.println method call:
case 'n': System.out.println(enterNumber);
Also note that Java is case sensitive, so you have to spell System with a capital letter.
On a side note, you will want to break; after each of your case statements, otherwise the code of the following cases will be executed as well:
switch (choice) {
case 'n': System.out.println(enterNumber);
break;
case 's': System.out.println(showNumber);
break;
case 'c': System.out.println(closeBook);
break;
default: System.out.println("Invalid Entry");
}
you do not have to write variable after 'cast' statement.
Refer below code.
import java.util.Scanner;
public class PhoneBook {
public static void main (String[] args){
options();
/*This method prompts the user to enter phone number
String s;
Scanner in = new Scanner(System.in);
System.out.println("Enter Phone Number");
s = in.nextLine();
System.out.println("You entered phone number ");
System.out.println(s);*/
}
public static void options (){
//This method gives the user choices on what to do
char choice;
char enterNumber = 'n';
char showNumber = 's';
char closeBook = 'c';
String read;
String freeLine = "error";
Scanner keyboard = new Scanner(System.in);
while (true){
System.out.println("Please select from the following");
System.out.println("n to Enter the number");
System.out.println("s to Show the number ");
System.out.println("c to Close the Phone book");
read = keyboard.nextLine();
choice = read.charAt(0);
switch (choice) {
case 'n':
System.out.println();
case 's':
System.out.println();
case 'c':
break;
default: System.out.println("Invalid Entry");
}
}
}
}
I have made a special answer for you. I don't add additional explanation. It's a large answer. I tell more than you ask, but I've done my best to make a readable code, so that you can analyse step-by-step to understand what you need at least when trying to make a Phone Book (console test drive application). If you need more explanation, write under comments.
First make a PhoneEntry class:
import java.util.Objects;
public class PhoneEntry implements Comparable<PhoneEntry> {
// https://jex.im/regulex/#!embed=false&flags=&re=%5E%5Ba-zA-Z%5D%7B2%2C%7D((-%7C%5Cs)%5Ba-zA-Z%5D%7B2%2C%7D)*%24
private static final String NAME_PATTERN = "^[a-zA-Z]{2,}((\\-|\\s)[a-zA-Z]{2,})*$";
// https://jex.im/regulex/#!embed=false&flags=&re=%5E%5C%2B%3F%5Cd%2B((%5Cs%7C%5C-)%3F%5Cd%2B)%2B%24
private static final String NUMBER_PATTERN = "^\\+?\\d+((\\s|\\-)?\\d+)+$"; //^\+?\d+((\s|\-)?\d+)+$
private final String name;
private final String number;
public PhoneEntry(String name, String number) {
if (!name.matches(NAME_PATTERN) || !number.matches(NUMBER_PATTERN)) {
throw new IllegalArgumentException();
}
this.name = name;
this.number = number;
}
public String getName() {
return name;
}
public String getNumber() {
return number;
}
public boolean nameContainsIgnoreCase(String keyword) {
return (keyword != null)
? name.toLowerCase().contains(keyword.toLowerCase())
: true;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof PhoneEntry)) {
return false;
}
PhoneEntry phoneEntry = (PhoneEntry) obj;
return name.equalsIgnoreCase(phoneEntry.name)
&& number.equalsIgnoreCase(phoneEntry.number);
}
#Override
public int hashCode() {
int hash = 5;
hash = 17 * hash + Objects.hashCode(this.name.toLowerCase());
hash = 17 * hash + Objects.hashCode(this.number.toLowerCase());
return hash;
}
#Override
public int compareTo(PhoneEntry phoneEntry) {
return name.compareToIgnoreCase(phoneEntry.name);
}
}
Then the test drive
public class TestDrive {
private static final String choices = "nspc";
enum Choice {
CREATE, READ, PRINT, CLOSE;
static Choice getChoice(char c) {
switch (c) {
case 'n':
return Choice.CREATE;
case 's':
return Choice.READ;
case 'p':
return Choice.PRINT;
case 'c':
return Choice.CLOSE;
}
return null;
}
}
// Main
public static void main(String[] args) {
Scanner kbd = new Scanner(System.in);
final Set<PhoneEntry> entries = new TreeSet<>();
Choice choice;
while ((choice = getChoice(kbd)) != Choice.CLOSE) {
switch (choice) {
case CREATE:
PhoneEntry entry = getPhoneEntry(kbd);
if (entry != null) {
entries.add(entry);
}
break;
case READ:
print(readEntries(entries, kbd));
break;
case PRINT:
print(entries);
break;
}
}
}
private static Choice getChoice(Scanner kbd) {
System.out.println("\nPlease select from the following");
System.out.println("\tn to Enter the number");
System.out.println("\ts to Show numbers by keyword ");
System.out.println("\tp to Show all numbers ");
System.out.println("\tc to Close the Phone book");
System.out.print("> ");
String input = kbd.nextLine();
Choice choice = null;
if (!input.isEmpty()
&& choices.contains(input.toLowerCase())
&& ((choice = Choice.getChoice(input.toLowerCase().charAt(0))) != null)) {
return choice;
}
System.out.println("ERR: INVALID ENTRY. TRY AGAIN");
return getChoice(kbd);
}
private static PhoneEntry getPhoneEntry(Scanner kbd) {
System.out.print("Type contact name: ");
String name = kbd.nextLine();
System.out.print("Type phone number: ");
String number = kbd.nextLine();
try {
return new PhoneEntry(name, number);
} catch (IllegalArgumentException ex) {
System.out.println("\nERR: WRONG ENTRY");
}
return null;
}
private static void print(Set<PhoneEntry> entries) {
System.out.println("\nPHONE NUMBERS\n");
entries.stream().forEach(entry -> {
System.out.printf("Name: %s%nPhone: %s%n%n",
entry.getName(), entry.getNumber());
});
}
private static Set<PhoneEntry> readEntries(Set<PhoneEntry> entries, Scanner kbd) {
System.out.print("Type keyword: ");
return entries.stream().filter(entry
-> entry.nameContainsIgnoreCase(kbd.nextLine()))
.collect(Collectors.toCollection(TreeSet::new));
}
}
Instead of enterNumber;, you have to write enterNumber();.
The parentheses mean: Call the method.
This question already has an answer here:
How to use java.util.Scanner to correctly read user input from System.in and act on it?
(1 answer)
Closed 6 years ago.
I'm currently on a project where I'm supposed to create a phonebook in java with eclipse, I'm almost done but there's still one part of my code that I don't understand.
The following code sample is the part giving me some troubles, my condition if(...contains(...)) always answers true even if none of the contact have this part of String in their name. Also the whole contacts of the phone are displayed while I would like only the one that match.
I've tried to do with if(...contains(..) == true) but it's not working either.
On the other hand the second part looking for a matching with ID works perfectly and give back only the concerned "i". Using the same code but adapted to my String also doesn't produce any good result.
public static void display(){
System.out.println("You selected display a contact, choose an option :");
System.out.println("1. by the first name");
System.out.println("2. by the last name");
System.out.println("3. by the ID");
System.out.println("4. by the phone number");
Scanner sc = new Scanner(System.in);
int str3 = sc.nextInt();
if(str3 == 1){
System.out.println("Please enter the first name of the contact");
String fname = sc.nextLine();
sc.nextLine();
for(int i = 0; i <= (phoneBook.size()-1) ; i++){
if(((phoneBook.get(i)).getFirstName()).toLowerCase().contains(fname.toLowerCase()) ){
displayContact(phoneBook.get(i));
}
}}
if(str3 == 2){
System.out.println("Please enter the last name of the contact");
String lname = sc.nextLine();
sc.nextLine();
for(int i = 0; i <= (phoneBook.size()-1) ; i++){
if(((phoneBook.get(i)).getLastName()).toLowerCase().contains(lname.toLowerCase())){
displayContact(phoneBook.get(i));
}
}
}
if(str3 == 3){
System.out.println("Please enter the ID of the contact");
int id = sc.nextInt();
for(int i = 0; i <= (phoneBook.size()-1) ; i++){
if(id == ((phoneBook.get(i)).getID())){
displayContact(phoneBook.get(i));
}
}
}
if(str3 == 4){
System.out.println("Please enter the phone number of the contact");
int phnb = sc.nextInt();
for(int i = 0; i <= (phoneBook.size()-1) ; i++){
if(phnb == phoneBook.get(i).getPhoneNb()){
displayContact(phoneBook.get(i));
}
}
}
System.out.println(" ");
System.out.println("If you want to go back at main menu press 1, else press 2 to quit.");
int str8 = sc.nextInt();
if(str8 == 1){
menu();
}
if(str8 == 2){
quit();
}
}
I think the usage of Scanner, first reading a nextInt, and then twice a nextLine might cause an empty string, and that is always contained. You could take the second nextLine, or alternatively, use a BufferedReader, which is less error prone.
public static void display(){
System.out.println("You selected display a contact, choose an option :");
System.out.println("1. by the first name");
System.out.println("2. by the last name");
System.out.println("3. by the ID");
System.out.println("4. by the phone number");
BufferedReader sc = new BufferedReader(new InputStreamReader(System.in));
int str3 = Integer.parseInt(sc.readLine());
switch (str3) {
case 1:
System.out.println("Please enter the first name of the contact");
String fname = sc.readLine();
for (int i = 0; i < phoneBook.size(); i++) {
if (phoneBook.get(i).getFirstName().toLowerCase().contains(fname.toLowerCase())) {
displayContact(phoneBook.get(i));
}
}
break;
case 2:
System.out.println("Please enter the last name of the contact");
String lname = sc.readLine();
for (int i = 0; i < phoneBook.size(); i++){
if (phoneBook.get(i).getLastName().toLowerCase().contains(lname.toLowerCase())) {
displayContact(phoneBook.get(i));
}
}
break;
case 3:
System.out.println("Please enter the ID of the contact");
int id = Integer.parseInt(sc.readLine());
for (int i = 0; i < phoneBook.size(); i++) {
if (id == phoneBook.get(i)).getID()) {
displayContact(phoneBook.get(i));
}
}
break;
case 4:
System.out.println("Please enter the phone number of the contact");
int phnb = Integer.parseInt(sc.readLine());
for(int i = 0; i < phoneBook.size(); i++){
if(phnb == phoneBook.get(i).getPhoneNb()){
displayContact(phoneBook.get(i));
}
}
break;
}
System.out.println(" ");
System.out.println("If you want to go back at main menu press 1, else press 2 to quit.");
int str8 = Integer.parseInt(sc.readLine());
if(str8 == 1){
menu();
}
if(str8 == 2){
quit();
}
}
As an extra the switch statement.
I am trying to take user input for name, last name, phone number and age.
For some odd reason the scanner is skipping name but none of the other variables.
Can someone point out my mistake please? I can't figure it out.
import java.util.Scanner;
public class Lab2{
String [][] info = new String [10][4];
public static void main(String [] args){
new Lab2();
}
public Lab2(){
Scanner input = new Scanner(System.in);
System.out.println();
System.out.println("Student contact Interface");
System.out.println("Please select a number from the options below:");
while(true){
System.out.println("1: Add a new contact.");
System.out.println("2: Remove an existing contact.");
System.out.println("3: Display the contact list.");
System.out.println("0: Exit the contact list.");
int options = input.nextInt();
String name, lastName, number, age;
switch(options){
case 1:
System.out.println("Please enter the name: ");
name = input.nextLine(); // This is the String var that is not accepting input from...
System.out.println("Please enter the last name: ");
lastName = input.nextLine();
System.out.println("Please enter the phone number: ");
number = input.nextLine();
System.out.println("Please enter the age (eg. 25): ");
age = input.nextLine();
addStudent(name, lastName, number, age);
break;
case 2:
System.out.println("\nEnter the name to remove: ");
String delName = input.nextLine();
System.out.println("\nEnter the last name to remove: ");
String delLastName = input.nextLine();
remove(delName, delLastName);
break;
case 3:
display();
break;
case 0:
System.out.println("Thank you for using the contact Database.");
System.exit(0);
}
}
}
public void addStudent (String name, String lastName, String number, String age){
boolean infoInserted = false;
for(int i = 0; i < 10; i++){
if(info[i][0] == null || info[i][0].equals(null)){
info[i][0] = name;
info[i][1] = lastName;
info[i][2] = number;
info[i][3] = age;
infoInserted = true;
break;
}
}
if(infoInserted){
System.out.println("\nContact saved.\n");
}
else{
System.out.println("\nYour database is full.\n");
}
}
public void remove(String delName, String delLastName){
boolean removed = false;
int i = 0;
for (i = 0; i < 10; i++) {
if (info[i][0] != null && !info[i][0].equals(null)) {
if (info[i][0].equals(delName) && info[i][1].equals(delLastName)) {
while (i < 9) {
info[i][0] = info[i + 1][0];
info[i][1] = info[i + 1][1];
info[i][2] = info[i + 1][2];
info[i][3] = info[i + 1][3];
i++;
}
info[9][0] = null;
info[9][1] = null;
info[9][2] = null;
info[9][3] = null;
removed = true;
break;
}
}
}
if (removed) {
System.out.println("Contact removed.");
}
else {
System.out.println("Contact was not found.");
}
}
public void display (){
for (int i = 0; i < 10; i++) {
if (info[i][0] != null && !info[i][0].equals(null)) {
System.out.println("Contact " + (i + 1)+ ":");
System.out.println("\t" + info[i][0]);
System.out.println("\t" + info[i][1]);
System.out.println("\tPhone Number:" + info[i][2]);
System.out.println("\tAge:" + info[i][3]);
}
}
}
}
Add a
input.nextLine();
after your
int options = input.nextInt();
This is because:
nextInt method does not read the last newline character (of your integer input)
that newline is consumed in the next call to nextLine
causing name 'to be skipped'
so you need to 'flush away' the newline character after getting the integer input
Another option:
Take in the entire line, using input.nextLine()
Get the integer value using Integer.parseInt() to extract the integer value
It is skipping name because , input.nextInt() wont go to next input line.
You can use
int option=Integer.parseInt(input.nextLine());
then it wont skip name.
//TestEmployeesProgram driver with menu & object array.
import java.util.*;
public class TestEmployeesProgram {
public static Scanner console = new Scanner(System.in);
public static void main(String[] args) {
final int MAX = 7;
Employee employee[] = new Employee[MAX];
int choice,k;
String name;
boolean notFound;
employee[0] = new Manager("Jerry Bloggs","gfr",5,38.5);
employee[1] = new Manager("Joe Bloggs","gdr",4,32.5);
employee[2] = new Admin("Mary Jennings","nnv",35.3,88.5,34.3);
employee[3] = new Clerk("Brian Jones","bbl",42.4,78.5,23.5,45.3);
employee[4] = new Manager("John Bloggs","gvr",5,33.5);
employee[5] = new Admin("Bridget Jennings","nvv",45.3,98.5,36.3);
employee[6] = new Clerk("Jack Jones","bbb",43.4,78.5,23.5,47.3);
//Initial Read
choice = showMenu();
//Continue Until 4/Exit
while (choice != MAX) {
switch (choice) {
case 1://Manager
System.out.println();
System.out.printf("%s %-16s %-10s %6s","Name","Id","Hours Worked","Pay");
System.out.println("\n==================================================");
for (k = 0; k < MAX; ++k)
{
if (employee[k] instanceof Manager){ //use of string method instance of.
System.out.println(employee[k].toString());
}
}
break;
case 2://Administration
System.out.println();
System.out.printf("%s %-16s %-10s %6s %-19s","Name","Id","Hours Worked","Pay","Admin Quota");
System.out.println("\n==================================================");
for (k = 0; k < MAX; ++k)
{
if (employee[k] instanceof Admin){
System.out.println(employee[k].toString());
}
}
break;
case 3://Clerk
System.out.println();
System.out.printf("%s %-16s %-10s %6s %-19s","Name","Id","Hours Worked","Pay","Admin Quota","Units Sold");
System.out.println("\n==================================================");
for (k = 0; k < MAX; ++k)
{
if (employee[k] instanceof Clerk){
System.out.println(employee[k].toString());
}
}
break;
I was running the program and the name search in case 4 goes directly to default "employee name not found" and doesnt allow user input.I looked through the code but cant find the error,any tips or help?
case 4://Name search
System.out.print("Enter employee name: ");
name = console.nextLine();
k = -1;
notFound = true;
while ((k < MAX-1) && (notFound))
{
++k;
if (name == employee[k].getName()){
System.out.println();
System.out.printf("%s %-16s %-10s %6s %-19s","Name","Id","Hours Worked","Pay","Admin Quota","Units Sold");
System.out.println("\n==================================================");
System.out.println(employee[k].toString());
System.out.println();
notFound = false;
}
}//end of case 4 while.
if (notFound){
System.out.println("Employee name not found\n");
}
break;
case 7://exit
System.out.println("Program exiting...");
System.exit(0);
default:
System.out.println("Invalid menu choice 1..3 of 7 to Exit");
}//end of switch
//sub read
choice = showMenu();
}//end of while
}//end of main
//Menu method for employee selection.
public static int showMenu()
{
int choice;
System.out.println();
System.out.println("Employee Program Menu");
System.out.println("1.Show Manager pay details ");
System.out.println("2.Show Admin pay details ");
System.out.println("3.Show Clerk pay details ");
System.out.println("4.Search by employee name ");
System.out.println("7.Exit");
System.out.print("Enter option: ");
choice = console.nextInt();
return choice;
}
}
There are two errors. The first is here:
System.out.print("Enter option: ");
choice = console.nextInt();
The nextInt method doesn't consume the end-of-line character. Try this instead:
System.out.print("Enter option: ");
String line = console.nextLine();
choice = Integer.parseInt(line);
The second error is that here you should use equals instead of == to compare strings:
if (name == employee[k].getName())
Try this instead:
if (name.equals(employee[k].getName()))
The == operator tests to see if the two strings are the same object (i.e. the strings are at the same location in memory).
if (name == employee[k].getName())
change this to
if (name.equals(employee[k].getName()))
This is a common issue. When you use nextInt() to read an integer value only the integer character is read and the \n is left in the buffer and when you call nextLine() after that, it doesn't prompt for user entry because it already got a '\n'
To avoid this, in the showMenu method do
console.nextLine();
after you get the choice using nextInt().
This last part of showMenu would be:
choice=console.nextInt();
console.nextLine();
return choice;
and you should use .equals() method to compare strings as below.
if (name.equals(employee[k].getName()))
Good luck :)