My static method to add an Object to an Arraylist of Objects.
public static void addObject() {
int id;
String name;
try{
System.out.print("Id: ");
id = Integer.parseInt(sc.next());
System.out.print("Name: "); //when the program gets here, he just skips back to my main class...
name = sc.nextLine();
Object o = new Object(id, name);
l.addObject(o); //adds the object to this list (l) of objects
}
catch(NumberFormatException nfe){
System.out.println("Not a valid id!");
addObject();
}
}
My main method which contains a switch in do-while-loop, which adds, deletes and edits objects.
public static void main(String[] args){
int choice;
do{
try{
choice = Integer.parseInt(sc.next());
switch (choice){
case 0: break; //ends the program
case 1: addObject(); break; //starting static method to add an object with a name and an id
//here are some more cases with similar static methods (left them out for simplicity)
default: System.out.println("Not a valid choice!");break;
}
}
catch(NumberFormatException nfe){
System.out.println("Not a valid choice!");
choice = -1; //to keep the loop running, and prevent another exception
}
}while (choice != 0);
System.out.println("Good bye!");
}
My Object class
public class Object{
private int id;
private String name;
public Object(int id, String name) {
this.id = id;
this.name = name;
}
}
My ObjectList class
import java.util.*;
public class ObjectList {
private List<Object> objects;
public ObjectList() {
objects = new ArrayList<Object>();
}
public void addObject(Object o){
objects.add(d);
}
}
When I try to run the static method to add an Object, it records the id of the object just fine, but when I enter the objects id, it goes back to my main method, starting the loop all over.
It reacts just fine when I enter a string in the switch(restarting the loop).
But I can't seem to add objects properly.
This is also a school assignment, in which they gave us all this code (except for the try-catch methods), and asked us to write a try-catch for the static method and the main method.
I could probably find a workaround for the main method with an if-clause, but I was wondering if this is possible with a try-catch method.
Issues:
When using a Scanner, you must be aware of how it does and doesn't handle the end of line token, especially when you combine method calls that handle this token (nextLine() for instance) and those that don't (nextInt() for instance). Note that the former, nextLine() swallows the end of line (EOL) token while nextInt() and similar methods don't. So if you call nextInt() and leave an end of line token tangling, calling nextLine() will not get your next line, but will rather swallow the dangling EOL token. One solution is to call sc.nextLine() right after calling sc.nextInt() just to hande the EOL token. Or else where you call sc.next(), change that to sc.nextLine().
Don't use recursion (having your addObject() method call itself) as you're doing where a simple while loop will work better, will be cleaner, and safer.
If you truly have a class named "Object", please change it as that name conflicts with the key base class of all Java classes.
For example, if you had this code:
Scanner sc = new Scanner(System.in);
System.out.print("Enter a number: ");
int number = sc.nextInt();
System.out.print("Enter name: ");
String name = sc.nextLine();
You'll find that the name is always "", and that is because the sc.nextLine() is swallowing the end of line (EOL) token left over from the user's entering a number. One way to solve this is to do:
Scanner sc = new Scanner(System.in);
System.out.print("Enter a number: ");
int number = sc.nextInt();
sc.nextLine(); // ***** to swallow the dangling EOL token
System.out.print("Enter name: ");
String name = sc.nextLine();
Related
I want to take input from user and then want to find is it Integer, float or something else. Till now I am using Scanner class for that. Like Scanner scan1=new Scanner(System.in);
String st= scan1.next(); and then I am trying to parse that input (st) in int and float respectively. But with this approach I am not able to satisfy the "else" condition. i.e. when input is neither string, int nor float.
Below is the code I tried :-
public String checkInput() {
String statement = "This input is of type ";
String inputType;
Scanner scan1 = new Scanner(System.in);
String st = scan1.next();
scan1.close();
inputType = st.getClass().getSimpleName();
try {
Float numFloat = Float.parseFloat(st);
inputType = numFloat.getClass().getSimpleName();
} catch (NumberFormatException e) {
}
try {
Integer numInt = Integer.parseInt(st);
inputType = numInt.getClass().getSimpleName();
} catch (NumberFormatException e) {
}
return statement + inputType;
}
here I am not able to decide how should I place else condition to check the input is neither string,float nor integer.
Here's how I would restructure your code. I'll explain the changes below:
private static final String STATEMENT = "This input is of type ";
public static String checkInput(Scanner scanner) {
if (scanner.hasNextFloat()) {
return STATEMENT + Float.class.getSimpleName();
else if (scanner.hasNextInt()) {
return STATEMENT + Integer.class.getSimpleName();
}
return STATEMENT + "UNKNOWN";
}
First, we pulled statement out into a constant, since it's not being changed.
Second, we pass the Scanner in as a parameter, rather than constructing a new one. There are a number of reasons to prefer this, but the principle one is that you should avoid creating multiple Scanner instances reading from System.in - generally you'll create such a Scanner in your main() method and pass it off to the methods and classes that need to use it.
Next, rather than reading from the scanner directly, we use the has*() methods to inspect the scanner's state without advancing it. This changes the semantics of checkInput(), because when it returns the input being inspected is still in the scanner, but that's more consistent with a method named check...() - it should inspect, not change state. Because your implementation calls .next() you lose the actual provided input, which is presumably undesirable.
Finally, we return from inside each block, rather than setting a temporary inputType variable and returning it at the end.
Your main() method might now look like this:
public static void main(String[] args) {
// using try-with-resources so we don't have to call .close()
try (Scanner scanner = new Scanner(System.in)) {
System.out.println(checkInput(scanner));
String input = scanner.next(); // this actually advances the scanner
System.out.println("You input: " + input);
}
}
Taking it further, you might prefer to have checkInput() return a Class<?> rather than a String, and then construct your statement separately. This would allow you to handle the inputs differently. For example:
public static Class<?> inputType(Scanner scanner) {
if (scanner.hasNextFloat()) {
return Float.class;
else if (scanner.hasNextInt()) {
return Integer.class;
}
// add other types as needed
return String.class;
}
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
Class<?> inputType = inputType(scanner);
String input = scanner.next();
System.out.println("You input: " + input);
if (inputType.equals(Integer.class)) {
System.out.prinln("That's a valid integer!");
}
}
}
All that said, we're very much reinventing the wheel here. The "right" way to use Scanner is to use the typed methods directly - e.g.:
if (scanner.hasNextInt()) {
int value = scanner.nextInt();
}
This avoids needing to do any manual type checking or similar busywork - just let Scanner do the validation for you.
import java.util.*;
class Player {
public static void main (String [] args) {
String number = Text.nextLine
}
}
I want the user input from this class and
bring into another class and use the number variable for a
If statement
I want the user input from this class and bring into another class and
use the number variable for a If statement.
It is simple take a look at below example(make sure to add both classes in one package different java files as Player.java and ExampleClass.java),
This is the class that Scanner has:
import java.util.*;
public class Player{
public static void main (String [] args){
Scanner getInput = new Scanner(System.in);
System.out.print("Input a number");
//you can take input as integer if you want integer value by nextInt()
String number = getInput.nextLine();
ExampleClass obj = new ExampleClass(number);
obj.checkMethod();
}
}
This is the class that check number:
public class ExampleClass{
int number;
public ExampleClass(String number){
try{
//If you want to convert into int
this.number = Integer.parseInt(number);
}catch(NumberFormatException e){
System.out.println("Wrong input");
}
}
public void checkMethod(){
if(number > 5){
System.out.println("Number is greater.");
}else{
System.out.println("Number is lesser.");
}
}
}
Few thing to mention:
Your example code contains syntax errors, fix those first.
If you want integer you can use getInput.nextInt() rather than
getInput.nextLine().
You can create getter and setters to set vaues and get values. In my example I just only set value through the constructor.
Use proper naming convention.
In my example I convert the String into integer inside the constructor and wrap with try-catch block to prevent from NumberFormatException(If you input character or something you can see wrong input will print). Sometimes in variaus situation it is not good to use try-catch in constructor. To learn more about this, please read Try / Catch in Constructor - Recommended Practice.
Where you normally make an import on the other class, just import the Player class and it should work
I'm not sure if I got it, I suppose you're using a scanner.
This is the way I would do that:
Scanner class:
public class ScannerTest {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("Insert a decimal:");
String inputValue = scanner.nextLine();
if(!new ScannerCalc().isNumeric(inputValue)){
System.out.println("it's not a number...");
break;
}
else
new ScannerCalc().checkNumber(inputValue);
}
}
}
ScannerCalc class:
public class ScannerCalc {
public boolean isNumeric(String s) {
return s != null && s.matches("[-+]?\\d*\\.?\\d+");
}
public void checkNumber(String number){
if(Integer.parseInt(number)%2==0)
System.out.println("it' even");
else
System.out.println("it's odd");
}
}
Pay attention on instantiation of classes to reuse methods.
If you want to make use of a local variable in another entity, it is better to pass it as an argument to a method of the other entity. For example
OtherClass.operation(scanner.nextLine()); // In case method is static
new OtherClass().operation(scanner.nextLine()); // In case method is not static
I'm new to java and programming. I am stuck on one section of an assignment given to me in which I have to create a login for two different types of user which will display two different menus depending on which login is used. I am using Eclipse and the console.
The two different types of user are Boss and Worker and they must login using a username and password. The Boss menu must have the following menu options after logging in:
Setup Worker Schedule
View Worker Schedule
Move Worker
The Worker menu must have the following menu options after logging in:
View Schedule
I'd really appreciate any help with this, thanks in advance.
EDIT:
Okay, so I now have the following code:
import java.util.Scanner;
public class Depot {
public static void main(String[] arguments){
String bossName;
String bossPassword;
String workerName;
String workerPassword;
System.out.println("Enter your name: ");
Scanner authenticate = new Scanner(System.in);
String userName = authenticate.nextLine();
System.out.println("Your username is " + userName);
System.out.println("Enter your password: ");
String passWord = authenticate.nextLine();
System.out.println("Your password is " + passWord);
if (userName.equals(bossName) && passWord.equals(bossPassword)) {
int selection;
Scanner bossMenu = new Scanner(System.in);
System.out.println("1. Setup Worker Schedule");
System.out.println("2. View Worker Schedule");
System.out.println("3. Move Worker");
System.out.println("4. Quit");
do {
selection = bossMenu.nextInt();
if (selection == 1) {
System.out.println("1");
}
else if (selection == 2) {
System.out.println("2");
}
else if (selection == 3) {
System.out.println("3");
}
else {
System.out.println("4");
}
}
while(selection != 4);
bossMenu.close();
}
else if (userName.equals(workerName) && passWord.equals(workerPassword)) {
int selection;
Scanner userMenu = new Scanner(System.in);
System.out.println("1. View Worker Schedule");
System.out.println("2. Quit");
do {
selection = userMenu.nextInt();
if (selection == 1) {
System.out.println("1");
}
}
while(selection != 2);
userMenu.close();
}
}
}
However, the following two lines of code are giving me an error:
if (userName.equals(bossName) && passWord.equals(bossPassword)) {
and
else if (userName.equals(workerName) && passWord.equals(workerPassword)) {
bossName, bossPassword, workerName and workerPassword may not have been initialized?
First, get the credentials through using the Scanner, here is a basic way to construct a Scanner object, you will need to have the following import statement at the very beginning of your code, before anything else:
import java.util.Scanner;
To create a Scanner, do the following:
Scanner scannerName = new Scanner(System.in);
That tells the Scanner to read from the input stream, which will be the keyboard. To get data from the Scanner, first prompt the user for the data you need, then use one of the Scanner's .next___ methods to retrieve the input and store in a variable. I'm not going to tell you which one to use, check out the Scanner page in the Java API and see if you can figure it out on your own.
It should look something like this:
System.out.println("Enter your name");
String userLoginString = scannerName.next____();
System.out.println("Enter your password");
String userPasswordString = scannerName.next____();
Once you have the credentials stored in String variables, I'll use userLoginString and userPasswordString as examples, you will need to validate these credentials against some stored values. So, create String variables bossName, bossPassword, workerName, workerPassword.
Once you have the user's credentials, I would perform validation on these login credentials. You could do that using the logical operators and methods of the String class, like so:
if (userLoginString.equals(bossName) && userPasswordString.equals(bossPassword)) {
// print the boss menu
}
else if (userLoginString.equals(workerName) && userPasswordString.equals(workerPassword)) {
// print the user menu
}
The logical && ("and") operator will ensure that the correct menu will be displayed only if the user's credentials match the stored credentials. If the user enters the correct name (boss or worker) but the wrong password (or vice-versa), the statements inside the braces will NOT execute.
UPDATE Here is a commented version of your code so far with some hints as to how to make it better. It will compile and run fine if you just provide values for the String variables at the top, but I have some more suggestions to make it a little nicer:
import java.util.Scanner;
public class Depot {
public static void main(String[] arguments){
// you need to initialize these to some value or else there is
// nothing to compare them with. I tried some dummy values and
// your code worked as expected, as long as the user entered the
// correct values in the prompt.
String bossName;
String bossPassword;
String workerName;
String workerPassword;
// you can just use one Scanner for the whole program, since they are
// both just reading input from the standard input stream. Replace the
// other Scanners with "input" and close "input" at the end
Scanner input = new Scanner(System.in);
System.out.println("Enter your name: ");
// not needed
Scanner authenticate = new Scanner(System.in);
String userName = authenticate.nextLine();
System.out.println("Your username is " + userName);
System.out.println("Enter your password: ");
String passWord = authenticate.nextLine();
System.out.println("Your password is " + passWord);
if (userName.equals(bossName) && passWord.equals(bossPassword)) {
// this could be declared at the top of the program instead of
// redeclaring in the if...else
int selection;
Scanner bossMenu = new Scanner(System.in);
System.out.println("1. Setup Worker Schedule");
System.out.println("2. View Worker Schedule");
System.out.println("3. Move Worker");
System.out.println("4. Quit");
do {
selection = bossMenu.nextInt();
if (selection == 1) {
System.out.println("1");
}
else if (selection == 2) {
System.out.println("2");
}
else if (selection == 3) {
System.out.println("3");
}
else {
System.out.println("4");
}
} while(selection != 4); // this is usually here
bossMenu.close();
}
else if (userName.equals(workerName) && passWord.equals(workerPassword)) {
// this could be declared at the top of the program instead of
// redeclaring in the if...else
int selection;
// don't need this one, just use "input" Scanner
Scanner userMenu = new Scanner(System.in);
System.out.println("1. View Worker Schedule");
System.out.println("2. Quit");
do {
selection = userMenu.nextInt();
if (selection == 1) {
System.out.println("1");
}
} while(selection != 2); // this is usually here
// you would close the "input" Scanner here
userMenu.close();
}
}
}
UPDATED AGAIN!!! A better way to implement the Boss and Worker would be through using inheritance and polymorphism. Start with an abstract superclass that has common characteristics of the Boss and Worker. I'll call this the Employee superclass. It has firstName, lastName, and password instance variables, and you should add getters and setters for each:
// abstract class, CANNOT be instantiated but can be used as the supertype
// in an ArrayList<Employee>
public abstract class Employee {
private String firstName;
private String lastName;
private String password;
public Employee() {
// don't have to do anything, just need this so you can instantiate
// a subclass with a no-arg constructor
}
// constructor that takes only the name of the Employee
public Employee(String firstName, String lastName) {
this(firstName, lastName, null);
}
// constructor that takes name and password
public Employee(String firstName, String lastName, String password) {
this.firstName = firstName;
this.lastName = lastName;
this.password = password;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
// and so on, for the lastName and password....
// you must implement this specifically in any subclass!
public abstract void getMenu();
}
Then, your Boss and Worker classes could extends this Employee class and they would have all of the same methods and instance variables. You just must provide an overridden getMenu() method in each, since that one was abstract in the Employee class. Here is a sample of what your Boss class should look like, you need to implement the getMenu() yourself and the Worker class:
public class Boss extends Employee {
// notice we don't need the instance variables in the class declaration,
// but they are here since they are part of Employee
public Boss() {
// don't need to do anything here, just allows no-arg constructor
// to be called when creating a Boss
}
// just calls the superclass constructor, could do more if you want
public Boss(String firstName, String lastName) {
super(firstName, lastName);
}
// just calls the superclass constructor, could do more if you want
public Boss(String firstName, String lastName, String password) {
super(firstName, lastName, password);
}
#Override
public void getMenu() {
// put the print statment for Boss's menu here
}
// don't need to re-implement other methods, we can use them since
// they are part of the superclass
}
Once you have the Employee, Worker, and Boss classes, you're ready to try and re-write your program to Objects in place of simple variables as you were doing before. Here is an example of how that would get started:
import java.util.Scanner;
public class EmployeeTester {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// can make workers and bosses able to be processed polymorphically
// by assinging their references to Employee variables, since
// and Employee is the supertype of each, a Worker "is an" Employee
// and a Boss "is an" Employee.
Employee worker1 = new Worker("Bob", "Worker");
Employee worker2 = new Worker("Sue", "Bush", "Password1");
Employee worker3 = new Worker();
Employee boss1 = new Boss("Jenny", "Boss");
Employee boss2 = new Boss("Bill", "OtherBoss", "Password2");
Employee boss3 = new Boss();
// if you're going to have a lot of workers and bosses, and you don't
// need named variables for each because their info will be included
// in their constructors, you could do this
Employee[] employees = {new Worker("Bob", "Bailey", "myPassword"),
new Worker("Sue", "Sarandon", "123Seven"),
new Boss("Jenny", "Strayhorn", "hardPassword"),
new Boss("Billy", "MeanGuy", "pifiaoanaei")};
// then, you could iterate through this list to check if a password
// entered matches a firstName, lastName, and password combination
// for ANY type of employee in the array, then call the getMenu()
// method on that employee, like so: (This could all be in a loop
// if you wanted to process multiple Employees...)
System.out.println("Enter firstName:");
// you figure out which Scanner method to use!
String firstName = input._____();
System.out.println("Enter lastName:");
String lastName = input._____();
System.out.println("Enter password:");
String password = input._____();
// figure out what get____() method of the Employee class
// needs to be called in each case, and what it should be
// compared to with the .equals() method.
for (int i = 0; i < employees.length; i++) {
if (employees[i].get______().equals(______) &&
employees[i].get______().equals(______) &&
employees[i].get______().equals(______)) {
// if all of those conditions are true, print the menu
// for this employee
employees[i].get_____();
// you could do more stuff here....
// breaks out of the loop, no need to check for anymore employees
break;
}
}
}
}
I'm trying to make a program that prints out the three numbers you input and then outputs the average of those numbers. After creating the methods needed, when I compiled the code, there were errors when using the methods with scores. I'm not sure how I can reference scores when calling mPrint() or average() on it.
When the code is compiled, it throws errors at the lines where scores.mPrint(3); and scores.average(); are. Those errors are:
The method (method here) is undefined for the type ArrayList<Double>.
I imported: java.util.ArrayList and java.util.Scanner
public class OOPtraining {
ArrayList<Double> scores = new ArrayList<Double>();
public void mPrint(Integer prints) {
for (Integer i =0;i<prints; i++) {
System.out.println(scores.get(i));
}
}
public void average() {
double divi = scores.get(0)+scores.get(1)+scores.get(2);
System.out.println(divi/3);
}
public void main(String[] args) {
ArrayList<Double> scores = new ArrayList<Double>();
Scanner reader = new Scanner(System.in);
// down here is where I input the scores and then add them to "scores"
System.out.println("Enter a score: ");
double score1 = reader.nextDouble();
while (true) {
System.out.println("Type a double-type number:");
try {
score1 = Double.parseDouble(reader.next());
break;
} catch (NumberFormatException ignore) {
System.out.println("Invalid input");
}
}
scores.add(score1);
System.out.println("Enter another score: ");
double score2 = reader.nextDouble();
while (true) {
System.out.println("Type a double-type number:");
try {
score2 = Double.parseDouble(reader.next());
break;
} catch (NumberFormatException ignore) {
System.out.println("Invalid input");
}
}
scores.add(score2);
System.out.println("Enter another score: ");
double score3 = reader.nextDouble();
while (true) {
System.out.println("Type a double-type number:");
try {
score3 = Double.parseDouble(reader.next());
break;
} catch (NumberFormatException ignore) {
System.out.println("Invalid input");
}
}
scores.add(score3);
//here is where I stop adding the scores to "scores"
scores.mPrint(3);
scores.average();
}
}
this.get(i)
This will fail compilation because the class you've declared does not have a get method. It's very unclear what exactly you're trying to do though.
I see what you're trying to do now, you're trying to access a member variable of your class, 'this' refers to the class you're in OOPTraining. What you're trying to do is access the scores ArrayList. For you to be able to do that scores would have to be a class variable and not a local variable in your main method. Have a look at that and that should get you started.
There must be some method named get() in same class where you are trying to call this.get(int)
Otherwise it will not work.
i think you are working with list ,and forgotten to extend it
this refers to some instance of your class OOPtraining. this.get(0) invokes the get() method on your class OOPtraining and passes 0 as the first and only argument to that method.
The problem is that your class OOPtraining doesn't have a get() method. You either need to add a get() method to OOPtraining or, more likely, figure out what you want get() to be invoked on and provide an instance of that class. Then the code will look like myList.get(0).
If this.get(i) fails then there are 2 mistakes you might have made.
First, your class might not have a method with name get. So to correct the error do define the get method in your class.
Secondly, if you do have a get method you probably might have defined it with the static key word. In this case remove the static key word from the method's definition. Another solution, will be to replace the this keyword by your class name. Static methods are independent of objects, so the can be called without even constructing one.
First of all and before posting my question let me ask you people to stop downvoting my questions even if they seem stupid to you ,this site is an important place for me, it helps me a lot with my java doubts which are many,a question ban would be an heavy setback for me, so be helpful even by not answering!
Now for the question,
I have this method were i assign a value to a setter method with user input
public void addName() {
Scanner input = new Scanner(System.in);
System.out.println("Do you want to add a citizen name?");
String answer = input.nextLine();
while (!answer.equals("y") || (!answer.equals("n"))) {
if (answer.equals("y")) {
String giveName = input.nextLine();
this.setName(giveName);
break;
} else if (answer.equals("n")) {
System.out.println("Not adding a name!");
break;
}else{System.out.println("Please choose y or n!");
answer = input.nextLine();}
}
}
this method is later called in main from object p1 and object p2 and being assigned a differend value for each one to the instance variable name
import java.util.ArrayList;
import java.util.Scanner;
public class MainClass {
public static void main(String[] args) {
ArrayList<Pessoas> lista = new ArrayList<Pessoas>();
Pessoas p1 = new Portugueses();
Pessoas p2 = new Alemaes();
p1.addName();
p2.addName();
System.out.println(p1.getName());
System.out.println(p2.getName());
}
}
but when i call the getName() method at the end of main both p1 and p2 have the same value!
Shouldn't each object get it´s own copy of an instance variable?
The Problem is in your addName()-function. Your running your loop(while (!answer.equals("y") || (!answer.equals("n")))) until a y or n is entered. So as soon as you enter it, your loop will stop.
In your loop your checking if the input that was made cotains a y or n. Now the problem should be clear. Your loop won't run with those two values entered, but inside the loop you want to check if one of those is entered.
Two little personal hints(everyone has another style): Don't use break; let your loops end themselfs. Do it with an boolean-variable and updating it's state.
The second hint would be to use one Scanner-Object. For example you could add a Scanner-parameter to your addName-function. Just init one in your MainClass.
Those hints and fixes of the problem applied to your code could look like that:
public void addName(Scanner input) {
System.out.println("Do you want to add a citizen name?");
String answer;
boolean isAnotherInputNeeded = true;
while (isAnotherInputNeeded) {
answer = input.nextLine();
if (answer.equals("y"))
{
System.out.println("What's the name?");
String giveName = input.nextLine();
this.setName(giveName);
isAnotherInputNeeded= false;
}
else if (answer.equals("n"))
{
System.out.println("Not adding a name!");
this.setName("No name entered");
isAnotherInputNeeded= false;;
}
else
{
System.out.println("Please choose y or n!");
}
input.reset();
}
}
And your MainClass:
import java.util.ArrayList;
import java.util.Scanner;
public class MainClass {
public static void main(String[] args) {
ArrayList<Pessoas> lista = new ArrayList<Pessoas>();
Pessoas p1 = new Pessoas();
Pessoas p2 = new Pessoas();
Scanner input = new Scanner(System.in);
p1.addName(input);
p2.addName(input);
System.out.println("You entered the following names:");
System.out.println(p1.getName());
System.out.println(p2.getName());
}
}
Hope that helps!