Hey i have an EmployeeStore which i have used a hashmap for this. The variables that the map stores are email name and id. I have a method called SearchByEmail but there is a problem with this. The method returns false when the user inputs a correct employee email into the UI.
Here is my code:
This is in the MainApp
case 2:
System.out.println("Search by Email.");
Employee employeeSearchEmail = MenuMethods.userInputByEmail();
Store.searchByEmail(employeeSearchEmail.getEmployeeEmail());
MenuMethods
//Imports
import java.util.Scanner;
//********************************************************************
public class MenuMethods
{
private static Scanner keyboard = new Scanner(System.in);
//Methods for the Company Application menu.
//Method for validating the choice.
public static int getMenuChoice(String menuString, int limit, String prompt, String errorMessage)
{
System.out.println(menuString);
int choice = inputAndValidateInt(1, limit, prompt, errorMessage);
return choice;
}
//********************************************************************
//This method is used in the getMenuChoice method.
public static int inputAndValidateInt(int min, int max, String prompt, String errorMessage)
{
int number;
boolean valid;
do {
System.out.print(prompt);
number = keyboard.nextInt();
valid = number <= max && number >= min;
if (!valid) {
System.out.println(errorMessage);
}
} while (!valid);
return number;
}
//********************************************************************
public static Employee userInput()
{
String temp = keyboard.nextLine();
Employee e = null;
System.out.println("Please enter the Employee Name:");
String employeeName = keyboard.nextLine();
System.out.println("Please enter the Employee ID:");
int employeeId = keyboard.nextInt();
temp = keyboard.nextLine();
System.out.println("Please enter the Employee E-mail address:");
String employeeEmail = keyboard.nextLine();
return e = new Employee(employeeName , employeeId, employeeEmail);
}
//********************************************************************
public static Employee userInputByName()
{
//String temp is for some reason needed. If it is not included
//The code will not execute properly.
String temp = keyboard.nextLine();
Employee e = null;
System.out.println("Please enter the Employee Name:");
String employeeName = keyboard.nextLine();
return e = new Employee(employeeName);
}
//********************************************************************
public static Employee userInputByEmail()
{
//String temp is for some reason needed. If it is not included
//The code will not execute properly.
String temp = keyboard.nextLine();
Employee e = null;
System.out.println("Please enter the Employee Email:");
String employeeEmail = keyboard.nextLine();
//This can use the employeeName's constructor because java accepts the parameters instead
//of the name's.
return e = new Employee(employeeEmail);
}
//********************************************************************
}
SearchByEmail
public boolean searchByEmail(String employeeEmail)
{
//(for(Employee e : map.values()) {...})
//and check for each employee if his/her email matches the searched value
boolean employee = map.equals(employeeEmail);
System.out.println(employee);
return employee;
}
First of all,
map.equals(employeeEmail);
doesn't really make sense. map is a Hashmap, and employeeEmail is a String. Under what conditions would they be equal?
It is unclear what you store in the map and how, since you have neither included the declaration of the map, nor the code that inserts new values. I'll assume for now that you store mappings like name -> Employee. If you want to search for an employee based on an email address I suggest you do something like
Employee findByEmail(String email) {
for (Employee employee : yourMap.values())
if (employee.getEmail().equals(email))
return employee;
// Not found.
return null;
}
then to check if an employee with email exists, you could do
public boolean searchByEmail(String employeeEmail) {
boolean employee = findByEmail(employeeEmail) != null;
System.out.println(employee);
return employee;
}
I assume map is of type Map<S,T> for some S,T, and thus it is not of the same type as employeeEmail, and specifically it does not equals() it.
I suspect you are looking for Map.containsValue() (if the email is the value in the map) or Map.containsKey() (if the email is the key of the map), depending on what exactly map is mapping, if the mapping is to/from the string value.
EDIT: based on clarifications on comments:
Since the email is not a key nor value in map, the suggested solution won't work as it is. So you can chose one of those:
Use #aioobe's solution to iterate and check each email.
Add an extra field to the class: Map<String,Employee> map2 which will map: email_address->employee. Given this map, you can search for an email using map2.containsKey(email). It will ensure faster lookup for an employee from an email and the expanse of holding an extra map. I'd go with this choice if I were you.
Related
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 have this method addPerson (on the main) which is used to set the name of a person.
private static Person[] addPerson(Person _person[], int _minAge, int _id){
int personAge;
String personName;
Scanner scan = new Scanner(System.in);
System.out.println("What's his age?");
personAge = scan.nextInt();
if(personAge >= _minAge){
if(!_person[_id].getPerson().equals("")){
System.out.println("Person " + _person[_id].getPerson() + " already exists.");
}else{
System.out.println("Enter the name of the person");
Scanner addPerson = new Scanner(System.in);
personName = addPerson.next();
_person[_id].setPerson(personName);
}
}else{
System.out.println("Person is not old enough");
}
return _person;
}
And here is the method setPerson in my custom class which is used to set the name of the person.
public void setPerson(String name){
System.out.println("Person added");
personName = name;
}
I know I should be doing the checking on whether that person already exists inside my setPerson method, but I am sort of confused with this. As you see I am expecting the user to input an integer, so I guess that I should check that right away to not get an error in case he inputs a string.
So my question is which should be checked within the same method and which on the method on my custom class?
Your code (and your question) is a bit confusing, but from what I can understand you want to know if you should check whether a person exists in the array in setPerson() or not?
Well, from what I can gather from your code, you should not do it in setPerson(), because that's a method in the Person class. The Person class shouldn't need to know anything about your array of Person objects.
So the way you're doing it now is probably your best bet.
Some general hints about the code:
There's no need to create a new Scanner, you can just use the one you have. So this
Scanner addPerson = new Scanner(System.in);
personName = addPerson.next();
becomes this
personName = scan.next();
I would also suggest you use the name setName()instead of setPerson()for your method name, it doesn't make sense to have it named one way when what it's actually doing is something else.
I would do it this way. However I don't have java currently so I didn't test this snippet.
class Person {
private String name;
public void setName(String name) {
this.name = name;
}
}
class Main {
private static final int minAge = 22;
private static Map<Person> addPerson(Map<Person> people, int id) {
if(people.containsKey(id)) {
// print that person with this id exists
return people;
}
Scanner scanner = new Scanner(System.in);
int age = scanner.nextInt();
if(age < minAge) {
// print that given age is invalid
return people;
}
String name = scanner.next();
people.get(id).setName(name);
return people;
}
}
I have a class as defined below:
public class CarHireSystem{
private static final Car[] carList = new Car[100];
private static int carCount = 0;
In this class, I have a menu where the user can add new Car. When they select this option they will be prompted with the following:
System.out.print("Enter car ID: ");
String carID = sc.nextLine();
System.out.print("Enter car description: ");
String cardescription = sc.nextLine();
System.out.print("Enter hire fee: $");
Double hireFee = sc.nextDouble();
sc.nextLine();
carList[carCount] = new Car(carID,carDescription,hireFee);
carCount++;
I would like a way to validate that the car ID entered into the array has not already been entered by the user and print an error message if it has been entered and go back to the main menu. How do I do this without using Hashmap.
Thanks
Check if it is already in the list or not, If not add it.
List<AdventureRide> list = new List();
AdventureRide ride = new AdventureRide(ID,description,admissionFee);
if(!list.contains(ride))
list.add(ride);
If you want to make it with the ID references, you can use a HashMap.
HashMap<Integer, AdventureRide> = new HashMap();
AdventureRide ride = new AdventureRide(ID,description,admissionFee);
if(!hm.containsKey(ID))
hm.put(ID,ride);
You have 2 options:
Go through the array each time you want to enter something and check that the current ID is not present within the array.
Have your AdventureRide override the equals and hashCode methods such that two elements are the same if they have the same ID. Once you have that, replace the array with Set<AdventureRide>. This will make sure you have entries with a unique ID.
I'd recommend you go for option 2, reason being that:
If down the line you need to check some other field, you would just need to change your equals and hashCode methods.
Since the Set is a dynamic data structure, you can add/remove from it without knowing the amount of entries before hand.
You could also use a Set<String> to store the ID, and call contains() or get() with a null check. Or store the AdventureRide instances in a Map<String,AdventureRide>. For example:
Map<String,AdventureRide> adventureMap = new HashMap<String,AdventureRide>();
...
private static final void addNewAdventure()
{
boolean idExists = false;
System.out.print("Enter ID: ");
String id;
do {
id = sc.nextLine();
if(null != adventureMap.get(id)) {
idExists = true;
System.out.println("The ID you entered already exists.\n Please enter a new ID: ");
}
} while(idExists);
System.out.print("Enter story: ");
String description = sc.nextLine();
System.out.print("Enter fee: $");
Double admissionFee = sc.nextDouble();
sc.nextLine();
adventureMap.put(id, new AdventureRide(id,description,admissionFee));
//keep track of objects in array
adventureCount++;
}
boolean exists = false;
for (AdventureRide ar : adventureList) {
if (ar != null && ar.getID().equals(ID)) {
exists = true;
break;
}
}
if (!exists) {
adventureList[adventureCount++] = new AdventureRide(ID, description, admissionFee);
}
Iterate over the array; if an element with the same ID exists, break the for loop and set the exists flag. Then at the end, check if the exists flag has been set. If not, then add the new element into the array.
You can auto generate a unique ID instead of letting user input it. This way, you don't even have to check the duplicated ID.
In your codes, instead of doing this:
adventureList[adventureCount] = new AdventureRide(ID,description,admissionFee);
Change it to:
adventureList[adventureCount] = new AdventureRide(description,admissionFee);
Then in your AdventureRide class:
class AdventureRide
{
private static int count = 0;
private String id;
public AdventureRide(String desc, double adminFee){
autoGenerateID(); //Auto generate formatted ID
}
private void autoGenerateID(){
DecimalFormat fmt = new DecimalFormat("T-00000");
id = fmt.format(count++);
}
}
DecimalFormat to format your ID to specific format. This is of course optional.
Output:
T-00000
T-00001
T-00002
T-00003
I am writing this program that will take in the names, ages and salaries for 5 different people from the user and will put them in an array.
I then want to write a method that will ask the user for another name, age and salary and add that into the array. Also a method that will as for the name of someone who's already in the array and will delete the information of the person with that age from the array.
The first method will increase the array size by 1 and the second will decrease the array size by 1. so far this is what I have:
ArrayList<details> details = new ArrayList<details>();
for(int x = 0; x < 4; x++) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter the first name: ");
String firstName = scan.nextLine();
System.out.println("Enter the last name: ");
String lastName = scan.nextLine();
System.out.println("Enter the age: ");
int age = scan.nextInt();
System.out.println("Enter the salary: ");
double salary = scan.nextDouble();
details.add (new details(firstName, lastName, age, salary));
}
I don't know how to go about doing this. I need some help!
thanks!
You can have a class Person with the class variables you require (name,age,salary)
class Person {
private int age;
private dobule salary;
private String firstname;
private String lastname;
}
Define the getter and setter methods for each of the class variables. For e.g
public void setAge(int age){
this.age = age;
}
public int getAge(){
return this.age;
}
In your main class read the input from STDIN as you are doing it. Instantiate the Person object for each of the 5 person.
Person employee = new Person();
employee.setAge(x);
employee.setFirstName(x);
employee.setLastName(y);
employee.setSalary(y);
Now, you can add each Person to your list and remove them too.
For removing any Person you would have to search for the Person through the ArrayList by name. That would be iterating over the length of ArrayList and comparing the name of each.
The final class would look like,
public class Solution{
private ArrayList<Person> details = new ArrayList()<Person>;
public static void main(){
// Here you loop for reading from STDIN as you are already doing.
// addPerson() would be used to add to ArrayList and removePerson() for the other
}
public addPerson(String firstName, String lastName, int age, int salary){
//Create the Person object
details.add(<person object>);
}
public removePerson(name){
details.remove(index);
// to get index it would require iterating over the ArrayList.
// It would be better if you use a Map instead (as other suggest)
// with name as the key
}
}
Hope this helps.
dud first of all, i can see that u have used arrayList name & Class name both same so please update that.
secondary use Map in place of Class like in if condition
if(){
Map userDetails = new HashMap();
map.put("firstname",firstname);
..
..
map.put("salary",scan.nextDouble());
details.add(map)
}
and on time of delete iterate ArrayList
for(int i=0;i<details.size();i++){
Map tempMap = details.get(i);
if(temp.get("firstname").toString() == "Given Name"){
}else{
// your logic
}
}
Hope will help you please let me know if any doubts.
use this code for removing employee
void removeEmployee(String name){
for(Employee emp :details){
if(name.equals(emp.getName())){
details.remove(emp);
break;
}
}
}
and do include exception handling
I asked a question earlier on this same project but I'm still having issues that I can't get through.
The project has a Person class, Validator class, Customer class, and Employee class. The Person class stores data about the person (name, email) the Customer class extends the person class and adds a customer number to the toString method. The Employee class also extends the Person class and extends a social security number to the toString method by overriding it.
At the bottom of the page I am trying to print the toString methods from my customer class OR my employee class. I want to make sure I am printing the right class based on what the user selected (if they are entering customer info or employee info)
The assignment specifically says "To print the data for an object to the console, this application should use a static method named print that accepts a Person object."
I think I have it started but I'm getting all kinds of red lines under what I have coded. Starting around the
public void toString()
line down towards the bottom.
I'm starting to think I am getting deeper into trouble by looking it up online so if someone can help me through it I would be greatful. My book doesn't show much on how to do this and all of the examples it shows seem to create the input and then print it but I'm trying to get the input from a user so I'm getting confused.
import java.util.Scanner;
public class PersonApp
{
public static void main(String[] args)
{
//welcome user to person tester
System.out.println("Welcome to the Person Tester Application");
System.out.println();
Scanner in = new Scanner(System.in);
//set choice to y
String choice = "y";
while (choice.equalsIgnoreCase("y"))
{
//prompt user to enter customer or employee
System.out.println("Create customer or employee (c/e): ");
String input = in.nextLine();
if (input.equalsIgnoreCase("c"))
{
String firstName = Validator.getString(in, "Enter first name: ");
String lastName = Validator.getString(in, "Enter last name: ");
String email = Validator.getEmail(in, "Enter email address: ");
String custNumber = Validator.getString(in, "Customer number: ");
Customer customer = new Customer(firstName, lastName, email, custNumber);
}
else if(input.equalsIgnoreCase("e"))
{
String firstName = Validator.getString(in, "Enter first name: ");
String lastName = Validator.getString(in, "Enter last name: ");
String email = Validator.getEmail(in, "Enter email address: ");
int empSoc = Validator.getInt(in, "Social security number: ");
Employee employee = new Employee(firstName, lastName, email, empSoc);
}
public void toString()
{
Person p;
p = c;
System.out.println(c.toString());
p = e;
System.out.println(e.toString());
}
System.out.println("Continue? y/n: ");
choice = in.nextLine();
System.out.println();
}
}
}
You can't define methods inside another method. The way you have the brackets, toString is defined inside main, which is illegal.
Also, you can't have toString return void, since it overrides the toString method from Object. Rename your method or have it return a String.
Your toString method needs to be moved out of your main method. It also needs to return a string. You'll probably have to call the method by some other name. Also, if Employee and Validator are in a separate package structure, you'll have to import that