I'm trying to build a text based to do list in Java but I'm having some difficulties when it comes to displaying the items.
When I run the code and enter "1" the contents of the to do list are displayed back to me, but they keep looping and they never stop. I'm assuming this has something to do with the while loop that checks the userChoice variable but my question is why does the list keep reiterating even after the break statement? What I'd like to have happen is to enter a number, have the action performed, and then have the instruction prompt displayed again.
java code:
package com.company;
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
// create an arraylist to store users items
static ArrayList<String> toDoList = new ArrayList<String>(3);
public static void main(String[] args) {
// greet the user
System.out.println("**Your To-Do list** \n");
// add default items to list
toDoList.add("Buy Groceries");
toDoList.add("Work Out");
toDoList.add("Play CS");
// user menu/instruction
System.out.println("Please select from one of the following options: \n 1. Show to-do list \n 2. Add item " +
"\n 3. Remove item \n 4. Exit program \n");
// prompt user for their choice
System.out.print("Enter your choice: ");
// get user choice
Scanner input = new Scanner(System.in);
int userChoice = input.nextInt();
while (userChoice != 4) {
switch (userChoice) {
case 1:
getToDoList();
break;
case 2:
// create method that allows you to add item to the toDolist
break;
case 3:
// create method that allows you to remove item from the toDolist
break;
case 4:
// create method that terminates application
break;
}
}
}
// method that returns contents of the list
public static void getToDoList(){
for (int i = 0; i < toDoList.size(); i++) {
System.out.println(toDoList.get(i));
}
}
}
It is because you did not request to read from user again.
case 1:
getToDoList();
input.nextInt();
break;
Or move the input.nextInt(); outside of switch block (below it).
Because userChoice is always 1, so it always loop.
import java.util.ArrayList;
import java.util.Scanner;
public class Groceries {
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<String> a=new ArrayList<String>();
a.add("Food");
a.add("Furniture");
a.add("Plywood");
while(true)
{
System.out.println("Enter your choice");
System.out.println("Your choice List\n 1:getList 2.addinthelist 3.removefromlist 4.exit");
Scanner sc=new Scanner(System.in);
int a1=sc.nextInt();
switch(a1)
{
case 1:
System.out.println(a);
break;
case 2:
System.out.println("List before addition of elemnt is :"+a);
System.out.println("Enter element to be added into the string");
String sss=sc.next();
a.add(sss);
System.out.println("List after addition of element is :"+a);
break;
case 3:
System.out.println("List before deletion of elemnt is "+a);
System.out.println("Enter an index of an element to be removed");
int abc=sc.nextInt();
a.remove(abc);
System.out.println("List after Deletion of an element is "+a);
break;
case 4:
System.exit(0);
default:
System.out.println("You entered wrong number !! Please enter 4 to exit");
}
}
}
}
Related
I am trying to create a pet app that allows user input to enter a pet name, update the pet name and delete the pet name. Here is what I have so far. I have made an array for the create method but I can't figure out how to use it in the update or delete methods.
import java.util.Scanner;
import java.io.*;
public class Menu2 {
static Scanner scan = new Scanner(System.in);
public static void main(final String[] args) {
showMainMenu();
}
public static void showMainMenu(){
System.out.println("--- MAIN MENU ---");
System.out.println("1. Create Pet");
System.out.println("2. Update Pet");
System.out.println("3. Delete Pet");
System.out.println("4. Exit");
System.out.print("Enter your Choice : ");
int option = scan.nextInt();
switch(option){
case 1:
createPet();
break;
case 2:
updatePet();
break;
case 3:
deletePet();
break;
case 4:
System.exit(0);
break;
default:
System.out.println("Invalid option!");
showMainMenu();
}
}
public static void createPet(){
Scanner myObj = new Scanner(System.in);
//String newPet = myObj.nextLine();
System.out.print("Enter Pet Name: ");
String newPet = myObj.nextLine();
String newPetArray[] = newPet.split(" ");
// newPet = scan.nextLine();
System.out.println("Pet Name is " + newPet);
// use for READ
for (int i = 0; i < newPetArray.length; i++){
System.out.println(newPetArray[i]);
}
showMainMenu();
}
public static void updatePet() {
}
public static void deletePet() {
}
}
If your goal is to store the pets in an array, for updating you would loop through the array (such as with a "for" or "while" loop), identify the index of the entry to be updated and update it. This could also be done with filters, but that would be a more advanced approach.
In order to delete the pet, you would need to find the pet (like you would in the update portion) and then shift all the remaining pets forward, so newPetArray[x] gets the value of newPetArray[x+1] and the last pet gets removed.
This task is easier with other datastructures, like ArrayList's, that support removing and inserting items directly.
As you haven't mentioned the details about the update function, I am assuming it is going to update the name of the pet present in the list. As ArrayList is more flexible when it comes to array in terms of addition of deletion and since you havent specified that you need to use array in particular, I'm providing the solution with ArrayList.
Logic for Updation
You iterate through the list and when the element matches, you simply update the name
Logic for Deletion
You iterate through the list and when the element matches, you simply remove the element present at that index.
import java.util.ArrayList;
import java.util.Scanner;
public class Menu2 {
static Scanner scan = new Scanner(System.in);
static ArrayList<String> petList;
public static void main(final String[] args) {
showMainMenu();
scan.close();
}
public static void showMainMenu() {
System.out.println("--- MAIN MENU ---");
System.out.println("1. Create Pet");
System.out.println("2. Update Pet");
System.out.println("3. Delete Pet");
System.out.println("4. Exit");
System.out.print("Enter your Choice : ");
int option = scan.nextInt();
switch (option) {
case 1:
createPet();
break;
case 2:
updatePet();
break;
case 3:
deletePet();
break;
case 4:
System.exit(0);
break;
default:
System.out.println("Invalid option!");
showMainMenu();
}
}
public static void createPet() {
Scanner myObj = new Scanner(System.in);
System.out.print("Enter Pet Name: ");
String newPet = myObj.nextLine();
String newPetArray[] = newPet.split(" ");
petList = new ArrayList<>();
// use for READ
for (int i = 0; i < newPetArray.length; i++) {
petList.add(newPetArray[i]);
}
System.out.println("pets in list are " + petList);
showMainMenu();
}
public static void updatePet() {
System.out.println("Enter the name of the pet to be updated");
String name = scan.next();
System.out.println("Enter the updated name");
String newName = scan.next();
for (int i = 0; i < petList.size(); i++) {
if (petList.get(i).equals(name)) {
petList.set(i, newName);
break;
}
}
System.out.println("pets in list after updating the pet " + petList);
showMainMenu();
}
public static void deletePet() {
System.out.println("Enter the name of the pet to be deleted");
String name = scan.next();
for (int i = 0; i < petList.size(); i++) {
if (petList.get(i).equals(name)) {
petList.remove(i);
break;
}
}
System.out.println("pets in list after deleting the specific pet " + petList);
showMainMenu();
}
}
and the output is as follows:
--- MAIN MENU ---
1. Create Pet
2. Update Pet
3. Delete Pet
4. Exit
Enter your Choice : 1
Enter Pet Name: buddy max mac
pets in list are [buddy, max, mac]
--- MAIN MENU ---
1. Create Pet
2. Update Pet
3. Delete Pet
4. Exit
Enter your Choice : 2
Enter the name of the pet to be updated
mac
Enter the updated name
macKing
pets in list after updating the pet [buddy, max, macKing]
--- MAIN MENU ---
1. Create Pet
2. Update Pet
3. Delete Pet
4. Exit
Enter your Choice : 3
Enter the name of the pet to be deleted
max
pets in list after deleting the specific pet [buddy, macKing]
--- MAIN MENU ---
1. Create Pet
2. Update Pet
3. Delete Pet
4. Exit
Enter your Choice : 4
I'm new to stackoverflow and wanted to know why my statement keeps on being repeated twice when i introduce an if statement in my while loop # "if done, type "back"". Secondly, can someone tell me why the ArrayList keeps an empty String at index 0 when i only add one item to the ArrayList? Thanks!
Here is the code:
package com.codewithrichard;
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
//global variables
boolean appIsStillOn = true;
ArrayList <String> shoppingList = new ArrayList<>();
System.out.println("Welcome to your mobile shopping list" + "\n" + "Your options are");
System.out.println("1) add item to list");
System.out.println("2) display list and amount of items in it");
System.out.println("3) quit!");
while (appIsStillOn) {
System.out.println("Option (1-4): ");
int option1 = input.nextInt();
if (option1 == 1) {
while (true) {
System.out.println("item (if done, type \"back\"): ");
String itemAdded = input.nextLine().toLowerCase();
if (!itemAdded.equals("back")) {
shoppingList.add(itemAdded);
} else {
break;
}
}
}
else if (option1 ==2){
System.out.println(shoppingList);
System.out.println("size of shopping list: " + shoppingList.size());
}
else {
System.out.println("Can't wait for you to come back!");
appIsStillOn = false;
}
}
}
}
The Scanner#nextInt() method (and many other next...() methods) does not consume the newLine character from the Scanner buffer which is produced when the ENTER key is hit. The Scanner#nextLine() method will consume it if encountered after a Scanner#nextInt() method therefore giving the impression that the prompt for input was skipped over.
Also Consider this...
What is to happen if the User accidentally types in an alpha character instead of a menu choice digit? That's right, your application will crash due to a InputMismatchException.
You should always carry out some form of validation for User input and if that validation fails, allow the User to make a proper entry. This obviously promotes a more trouble free environment when using your application. Using your current model, here is an example of this:
java.util.Scanner input = new java.util.Scanner(System.in);
//global variables
boolean appIsStillOn = true;
ArrayList<String> shoppingList = new ArrayList<>();
System.out.println("Welcome to your mobile shopping list.");
while (appIsStillOn) {
int option1 = 0;
while (option1 < 1 || option1 > 3) {
System.out.println();
System.out.println("Your Shopping List options are:");
System.out.println(" 1) Add item to list.");
System.out.println(" 2) Display list and amount of items in it.");
System.out.println(" 3) Quit!");
System.out.print("Choice (1-3): --> ");
try{
option1 = input.nextInt();
if (option1 < 1 || option1 > 3) {
throw new java.util.InputMismatchException();
}
/* Consume the enter key hit (newline char) in case
a Scanner#nextLine() prompt is next so that it
doesn't get consumed by that method. */
input.nextLine();
}
catch (java.util.InputMismatchException ex) {
System.err.println("Invalid menu choice supplied! Try again...");
/* Consume the enter key hit (newline char) in case
a Scanner#nextLine() prompt is next so that it
doesn't get consumed by that method. It is also
required here in case an exception has bypassed
the above 'input.nextLine()' call.*/
input.nextLine(); // Consume the enter key hit (newline char)
}
}
if (option1 == 1) {
while (true) {
System.out.println();
System.out.println("Enter the item to add (when done, enter \"back\"): ");
System.out.print("Item: --> ");
String itemToAdd = input.nextLine();
if (itemToAdd.trim().equals("")) {
System.err.println("Invalid Item String! You must supply something!");
continue;
}
else if (itemToAdd.equalsIgnoreCase("back")) {
break;
}
shoppingList.add(itemToAdd);
}
}
else if (option1 == 2) {
System.out.println();
System.out.println(shoppingList);
System.out.println("Number of Items in shopping list: " + shoppingList.size());
}
else {
System.out.println();
System.out.println("Bye-Bye - Can't wait for you to come back!");
appIsStillOn = false;
}
}
After take input input.nextInt(), when you press enter input.nextLine().toLowerCase() takes the data of that line since input.nextInt() doesn't take \n(newline).
Read the newline to skip it after input.nextInt()
int option1 = input.nextInt();
input.nextLine();
I've been working on a few projects recently and I can't seem to fully crack how to go from a menu option which takes you into a method, but then from that method return to the menu and prompt the user with the same options?
String userChoice = console.nextLine();
do {
switch (userChoice) {
case "1":
enteringContacts();
break;
case:"xyz"
}
}while(!userChoice.equals("xyz"));
I've used a do While loop but instead it just repeats the method? The method "EnteringContacts" is shown below:
public static void enteringContacts(){
Scanner console = new Scanner(System.in);
System.out.println("Welcome, How to use the system:");
System.out.println("Enter the contacts name, then press enter");
System.out.println("Enter the contacts number, then press enter");
String exitContactInsert = " ";
do {
contactName.add(console.nextLine());
contactNumber.add(console.nextLine());
System.out.println("Do you wish to add another?");
exitContactInsert = console.nextLine();
if (exitContactInsert.equals("no")) {
return;
} else {
System.out.println("Please enter another contact");
}
} while (exitContactInsert.equals("yes"));
}
Any help is appriciated!
Because you should ask user again for his choice every loop, before looping the "while" again.
add
userChoice = console.nextLine();
before line:
}while(!userChoice.equals("xyz"));
You should try to reorganize the code and to separate the logic from the user dialogs. You can provide an enum with possible actions:
public enum UserAction {
EDIT_CONTACT,
ADD_CONTACT,
...,
QUIT
}
And for example your logic class:
class Logic {
public void mainLoop() {
while (true) {
UserAction action = UserDialogs.getUserAction();
switch(action) {
case EDIT_CONTACT:
editContact();
break;
case ...
case QUIT: return;
}
}
}
}
And you should move a responsibility of parsing entered text in options to the dedicated class with static methods:
class UserDialogs {
public static UserAction getUserAction() {
System.out.println("Select an action (1-edit, 2-add, 3-..., Q-quit):");
Scanner scanner = new Scanner(System.in);
while (true) {
String response = scanner.nextLine().toUpperCase();
switch (response) {
case "1" : return EDIT_CONTACT;
case "2" : return ADD_CONTACT;
case ...
case "Q" : return QUIT;
default:
System.out.println("Wrong selection, try again");
}
}
}
}
If you'll be taking user response in the loop, then each iteration will be determined separately, performing different action each time until user will provide xyz.
String userChoice;
do {
userChoice = console.nextLine();
switch (userChoice) {
case "1":
enteringContacts();
break;
case:"xyz"
}
}while(!userChoice.equals("xyz"));
I'm trying to make a text-based game in Java. and I am going to have a lot of switch-statement with scanner, but I'm not sure which way would be the best.
What would be a best way to make switch-statement with Scanner?
is try+catch better? or do loop?
and if I have, let's say, 10 switch-statement. Is it better to have 10 different Scanner declared for each switch-statements?
I like to have try+catch styled switch-statement with individual Scanner in it, but someone said that it is not necessary, and take too much wasting memory this way. I prefer to recall the method when a wrong type input was put in, and I think try+catch was better in this way because when it was recalled it also recalled Scanner and Random, giving us a chance to reset the input a User put in and also the randomly generated number by Random.
These code down here are examples.
and is the code here not a good code?
(just when it comes to the try+catch, scanner usages)
public static void levelUpAsk_111(Character chosenMember) {
try {
Random rand = new Random();
Scanner sc = new Scanner(System.in);
int dicePercent = rand.nextInt(6) + 1;
int num = sc.nextInt();
if (num == dicePercent ) {
System.out.println("** Congratulation!!");
sc.nextLine();
System.out.println("**Which one would you like to increase?");
System.out.println("1. +20 HP");
System.out.println("2. +10 MP");
System.out.println("3. +5 ATT");
levelUpAsk_222(chosenMember); //the second method
} else if (num > 7 || num < 1) {
System.out.println("Please from 1 to 6");
levelUpAsk_111(chosenMember); //recall itself
} else {
System.out.println("** Sorry..");
sc.nextLine();
}
} catch (InputMismatchException e) {
System.out.println("Please integer only");
levelUpAsk_111(chosenMember); //recall itself
}
}
public static void levelUpAsk_222(Character chosenMember) {
try {
Scanner sc = new Scanner(System.in);
int select = sc.nextInt();
switch (select) {
case 1:
System.out.println("** HP has increased by 20.");
break;
case 2:
System.out.println("** MP has increased by 10.");
break;
case 3:
System.out.println("** ATT has incrased by 5.");
break;
default:
System.out.println("From 1 to 3");
levelUpAsk_222(chosenMember); //recall itself
break;
}
} catch (InputMismatchException e) {
System.out.println("Only integer please"); //recall itself
levelUpAsk_222(chosenMember);
}
}
For switch statements, you do not need to create a new Scanner object each time you want to use it. You can declare it once at the beginning of each method. It is more confusing if you have to deal with multiple Scanner objects in your code than if you only have one.
You can create use a switch looping menu with a default: to catch the unlisted inputs. For example
switch (option){ //assuming you declared option to an int and user has inputted a value for it
case 1:
{
//put some code here
break;
}
case 2:
{
//put more code here
break;
}
case 0:
{
//used to exit the loop
break;
}
default:
{
System.out.println("Please enter a integer only");
levelUpAsk_111(chosenMember); //you can do it this way, or use a do-while looped switch menu that keeps asking until a valid int is input
}
}
I am trying to call a method from another method in the same class, for example when the "enterValues" method is finished, I want it to go back to the main menu. Can someone please explain how I can do this? I am also a bit confused on the use of objects here, am I right in thinking I need to create an object in every method like I have done here, in order to call other methods?
import java.util.Scanner;
public class Conversion {
int value;
public void mainMenu() {
int menuChoice;
Scanner menuScan = new Scanner(System.in);
Conversion mainMenu = new Conversion();
System.out.println("1. Enter values and type -1 to stop");
System.out.println("2. Euros");
System.out.println("3. Dollars");
System.out.println("4. Yen");
System.out.println("5. Rupees");
System.out.println("6. Exit");
while (!menuScan.hasNextInt() || (menuChoice = menuScan.nextInt()) > 6) {
menuScan.nextLine();
System.err.println("Please enter a valid menu option 1 - 6: ");
}
switch (menuChoice) {
case 1:
mainMenu.enterValues();
case 2:
}
}
public void enterValues() {
Conversion enterValues = new Conversion();
Scanner valueScan = new Scanner(System.in);
System.out.print("Enter value to convert: ");
value = valueScan.nextInt();
System.out.println("Value entered. Returning to main menu.");
valueScan.close();
enterValues.mainMenu();
}
public static void main(String[] args) {
Conversion main = new Conversion();
main.mainMenu();
}
}
When you are inside a non-static method, you already are in an instance of your Class, so no need to create another instance.
Also, when you are in an instance of a class, you just call other methods directly, like mainMenu();
I modified your code a bit to reflect this :
import java.util.Scanner;
public class Conversion {
int value;
public void mainMenu() {
int menuChoice;
Scanner menuScan = new Scanner(System.in);
System.out.println("1. Enter values and type -1 to stop");
System.out.println("2. Euros");
System.out.println("3. Dollars");
System.out.println("4. Yen");
System.out.println("5. Rupees");
System.out.println("6. Exit");
while (!menuScan.hasNextInt() || (menuChoice = menuScan.nextInt()) > 6) {
menuScan.nextLine();
System.err.println("Please enter a valid menu option 1 - 6: ");
}
switch (menuChoice) {
case 1:
enterValues();
case 2:
}
}
public void enterValues() {
Scanner valueScan = new Scanner(System.in);
System.out.print("Enter value to convert: ");
value = valueScan.nextInt();
System.out.println("Value entered. Returning to main menu.");
valueScan.close();
mainMenu();
}
public static void main(String[] args) {
Conversion main = new Conversion();
main.mainMenu();
}
}
You must not create a new object every time you call a method. Within a class you can call any method you want.
If you finish one method, you continue where you called it. So in order to keep the main menu open you would have to use a loop or something similar.
The call itself is nothing more than:
mainMenu();
respectively
enterValues();
without creating a new Conversion.
You don't want to call mainMenu from enterValues, you want to return to it.
Make a "forever" loop inside mainMenu, and add an exit condition with a break. This way simply returning from enterValues or any other method inside mainMenu would bring you back to printing main menu and asking what else you wish to do:
public void mainMenu() {
mainLoop: while (true) {
int menuChoice;
Scanner menuScan = new Scanner(System.in);
Conversion mainMenu = new Conversion();
System.out.println("1. Enter values and type -1 to stop");
System.out.println("2. Euros");
System.out.println("3. Dollars");
System.out.println("4. Yen");
System.out.println("5. Rupees");
System.out.println("6. Exit");
while (!menuScan.hasNextInt() || (menuChoice = menuScan.nextInt()) > 6) {
menuScan.nextLine();
System.err.println("Please enter a valid menu option 1 - 6: ");
}
switch (menuChoice) {
case 1:
mainMenu.enterValues();
break;
case 2:
break;
case 6:
break mainLoop;
}
}
}