I can only access first item in the list - java

public class Catalogue() {
private List<Book> booksAvailable;
private List<Book> booksRented:
public Catalogue() {
booksAvailable.add(new Book("Matrix", 1999, new Genre("SciFi"), 3));
booksAvailable.add(new Book("Jurassic Park", 1999, new Genre("SciFi"), 3));
boosAvailable.add(new Book("Terminator", 1999, new Genre("SciFi"), 3));
booksRented = new LinkedList<Book> ();
}
public void rentBook() {
System.out.println("Rent a book:");
System.out.println("Enter the title of a book you want to rent: ");
String name = In.NextLine();
for (Book book: booksAvailable) {
if (book.getName.equals(name)) {
System.out.println("Renting " + name);
booksAvailable.remove(book);
booksRented.add(book);
break;
} else {
System.out.println("No such books found");
}
}
}
}
While running this code can only rent the Matrix book. When I try to rent another book like Jurassic park it says that no books found. When I close the program and again run it and try to rent the second book then it again says the books not found. Please help me with this problem. What is the problem that i have in this code. Thanks

As others have pointer out modifying a list while you're iterating over it is dangerous.
I would recommend trying it with a HashMap instead, especially if name is the only field you're looking at.
public class Catalogue {
private Map<String, Book> booksAvailable;
private Map<String, Book> booksRented;
public Catalogue() {
booksAvailable = new HashMap<>();
booksAvailable.put("Matrix", new Book("Matrix", 1999, new Genre("SciFi"), 3));
booksAvailable.put("Jurassic Park", new Book("Jurassic Park", 1999, new Genre("SciFi"), 3));
booksAvailable.put("Terminator", new Book("Terminator", 1999, new Genre("SciFi"), 3));
booksRented = new HashMap<>();
}
public void rentBook() {
System.out.println("Rent a book:");
System.out.println("Enter the title of a book you want to rent: ");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
if (booksAvailable.containsKey(name)) {
Book book = booksAvailable.get(name);
System.out.println("Renting " + name);
booksAvailable.remove(name);
booksRented.put(name, book);
} else {
System.out.println("No such books found");
}
}
}

I just tried your code(after modifying it to compile) and it works.
However when running on for example Jurasic Park it will say that the book is not found and then it will rent it, because that print statement is in the for loop.
I tried rewriting it to use streams and optionals, and I got this code that seems to be working
public void rentBook() {
System.out.println("Rent a book:");
System.out.println("Enter the title of a book you want to rent: ");
String name = "Jurassic Park";
Optional<Book> book = booksAvailable.stream().filter(b -> b.name.equals(name)).findFirst();
if(book.isPresent()) {
System.out.println("Renting " + name);
booksAvailable.remove(book.get());
booksRented.add(book.get());
}
else
System.out.println("No such book found");
}

When you call booksAvailable.remove() it will effectively removed from current iteration.
Hence when you access next(), it might result in unexpected behavior.
Edit
You cannot rent other book other than first book because of your code handling.
You have System.out.println("No such books found"); in the else statement inside loop. So if you input a book other than the first book, the test fail and the statement is printed.
To correct this you can use a flag to indicate a book is found or not, and print the statement outside the loop;
boolean rented = false;
for (Book b : books) {
if (found) {
rented = true;
}
}
if (!rented) {
// print no such book message
}

Related

ArrayList in Class A and user trigger the output from Class B. How do I correctly get an output from an ArrayList?

I doing a bigger school project (first part of basic objective programming in java - so not touched extended, polyphorism etc yet, thats next part), but run in to a small problem and tried for couple of days to find solution (thru books and internet). I constructed different ArrayLists in one class and different classes (at least two) should get access to them.
public class Customer
{
public void subMenuCustomer()
{
............code............
int subMenuCust;
ServiceLogic addCustomer = new ServiceLogic();
ServiceLogic listAllCustomers = new ServiceLogic();
while(true)
{
System.out.println("Please Choose your preference: ");
System.out.println("Create account, press \"1\": ");
System.out.println("Get list of clustomers, press \"2\": ");
System.out.println("Log out, press \"0\": ";
subMenuCust = input.nextInt();
switch(subMenuCust)
{
case 1 ://Call method createCustomer in class ServiceTech to add new customers
addCustomer.createCustomer(name, lastname, ssNo);
break;
case 3
listAllCustomers.getCustomer();
............more code..............
}
}
When user has added details (social secuity number, name and lastname) it is stored in seperate ArrayList. These three ArrayList are added(merge/concat) together to a fourth ArayList, listCustomer , so that all elements from the three ArrayList end up in same index [101 -54 Clark Kent, 242-42 Linus Thorvalds, ...].
import java.util.ArrayList;
import java.util.Scanner;
public class ServiceLogic
{
//Create new ArrayLists of Strings
private ArrayList<String> listSSNoCustomers = new ArrayList<>();
private ArrayList<String> listNameCustomers = new ArrayList<>();
private ArrayList<String> listLastnameCustomers = new ArrayList<>();
private ArrayList<String> listCustomers;
Scanner input = new Scanner(System.in);
public boolean createCustomer(String name, String lastname, String ssNo) //
{
System.out.println("Write social security number; ");
ssNo = input.next();
//loop to check that it is a uniq social security number
for(String ssNumber : listSSNoCustomers)
{
if (ssNumber.equals(ssNo))
{
System.out.println("This customer already exist. Must be uniq social security number.");
return true;
}
}
//If social security number is not on list, add it
//and continue add first name and surname
listSSNoCustomers.add(ssNo);
System.out.println(ssNo);
System.out.println("Write firstname; ");
name = input.next();
listNameCustomers.add(name);
System.out.println(name);
System.out.println("Write lastnamame; ");
surname = input.next();
listSurnameCustomers.add(lastname);
System.out.println(lastname);
return false;
}
public void setListCustomer(ArrayList<String> listCustomers)
{
this.listCustomers = listCustomers;
}
public ArrayList<String> getCustomer()
{
//ArrayList<String> listCustomers = new ArrayList<>();
for(int i = 0; i <listSSNoCustomers.size(); i++)
{
listCustomers.add(listSSNoCustomers.get(i) + " " + listNameCustomers.get(i) + " " + listFirstnameCustomers.get(i));
}
System.out.println("customer" + listCustomers);
return listCustomers;
}
}
According to the specification we got, when user want to see list of all customer the outputs should be in format [666-66 Bruce Wayne, 242-42 Linus Thorvalds, ...].
When user (staff) choose to enter details in class Customer ( Case 1 ) it works and elements get stored in the Arraylists for social security numbers, name and lastname (have checked that) .
The problem: when I run I can add customers, but when I try to get a list of customer the output: [] . I tried different solution, but same output only empty between the brackets.
So the question, how do I get ouput to work when user choose case 2 to get a list of all cutomers?

Unable to call required method from relevant class

I have a task where I need to create a program for "TotalCompetitions", which consists of multiple "Competition". I need to create an application which allows user to do various options related to TotalCompetition.
If the first option ("Create a new competition") is selected, by typing "1" and then pressing Enter,
the program should call the addNewCompetition method of the TotalCompetitions class to add
a new competition with a given name. After creating a new competition, the program should goes
back to the main menu.
The second option is to add entries to the competition. However, when I try to call the addEntry() method located in the Competition class to the newly created competition, it doesn't work as it is still of TotalCompetitions type. How can I access the newly created competition to access the required method?
At the moment, this is my code:
public class TotalCompetitions {
private ArrayList<Competition> competitions;
public TotalCompetitions() {
this.competitions = new ArrayList<Competition>();
}
public ArrayList<Competition> getCompetitions() {
return competitions;
}
public void setCompetitions(ArrayList<Competition> competitions) {
this.competitions = competitions;
}
public Competition addNewCompetition(String name, int id) {
Competition newCompetition = new Competition(name, id);
return newCompetition;
}
}
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
TotalCompetitions sc = new TotalCompetitions();
int competitionId = 0;
while (true) {
System.out.println("Please select an option. Type 5 to exit.");
System.out.println("1. Create a new competition");
System.out.println("2. Add new entries");
System.out.println("3. Draw winners");
System.out.println("4. Get a summary report");
System.out.println("5. Exit");
String command = keyboard.next();
if (command.equals("1")) {
keyboard.nextLine();
System.out.println("Competition name:");
String name = keyboard.nextLine();
competitionId += 1;
sc.addNewCompetition(name, competitionId);
System.out.println("A new competition has been created!");
System.out.println("Competition ID: " + competitionId + ", Competition Name: " + name);
}
else if (command.equals("2")) {
sc.addEntry();
}
else if (command.equals("5")) {
System.out.println("The end");
break;
}
}
sc.addNewCompetition(name, competitionId); returns a new object of the type Competition, however, this new object is not used by your program. The variable sc is still of the type TotalCompetition which is not related to the type Competition. Furthermore, your method addNewCompetition(String id, int id) does not add the new Object to the ArrayList. The solution would be to store the object which is returned by the sc.addNewCompetition(...) call and call addEntry() on this object.

Searching for a book title using linked list in java

I am trying to write a program where a user can search for a book by entering the title of the book. I used linked list to store a few book. I created a method called findBook with a string parameter. When I ask the user to search for a book and run the method, it does not work, but when I input the the title of the book in the findBook method in the code, it works. Here is some of my code that doesn't work:
book.insertBook("The Great Gatsby", "Scott Fitzgerald", 12345);
book.insertBook("To Kill a Mockingbird", "Harper Lee", 23456);
public Library findBook(String bookName)
{
Library theBook = firstBook;
if(!isEmpty())
{
while(theBook.bookName != bookName)
{
if(theBook.next == null)
{
return null;
}
else
{
theBook = theBook.next;
}
}
}
else
{
System.out.println("Our Library is empty");
}
public void searchBookTitle()
{
Scanner keyboard = new Scanner(System.in);
System.out.println("Here is a list of current books we have");
book.display();
System.out.println("Enter the Title of the Book you would like to check out");
String bookTitle = keyboard.nextLine();
String findBookTitle = book.findBook(bookTitle).bookName;
System.out.println(findBookTitle + " was found");
}
When I change the searchBookTitle method to this, it works, but I want the user to input the title:
public void searchBookTitle()
{
String findBook = book.findBook("Of Mice and Men").bookName;
System.out.println(findBook + " was found");
}
you should compare strings by equals():
if(!isEmpty())
{
while(!theBook.bookName.equals(bookName))
{
if(theBook.next == null)
{
return null;
}
else
{
theBook = theBook.next;
}
}
}
else
{
System.out.println("Our Library is empty");
}
This compares the references:
while(theBook.bookName != bookName)
You need to compare the string values:
while(!theBook.bookName.equals(bookName))
It found the book when you searched for book.findBook("Of Mice and Men") because the compiler optimized it and used the same String reference. If you would've search for findBook("The " + "Great Gatsby"), then it wouldn't find it, because it would create a new String with a different reference.

Java for loop with if statement only iterating once

I have a version of a login for an employee system i would like to make, I have a for loop which should go through the entire list of Accounts, then see if the name of an employee matches one in the list then the if statement continues, further questions asked etc... it seems to only iterate once and then stop as it will only find the first user and tell me the other accounts do not exisit, even though they do!! What am i doing wrong? Also my list contains Employees and Managers which inherit from Account, the if statement uses the getName in Account to compare if it equals to the user input. Sorry if this is ridiculously stupid/bad! thanks.
List <Account> Accounts = new LinkedList<Account>();
Here is where i populate my Account, the main method calls this and the list() is called whihc contains the problematic loop
public void add() {
Employee Geoff = new Employee("Geoff", "password1");
Manager Bob = new Manager("Bob", "password2");
Employee John = new Employee("John", "password3");
Accounts.add(Geoff);
Accounts.add(Bob);
Accounts.add(John);
list();
}
problem:
System.out.println("Hello welcome: ");
System.out.println("Please enter your name: ");
String empName = Scan.nextLine();
for (Account a : Accounts) {
System.out.println(a);
if (a.getname().equals(empName)) {
System.out.println("\nPlease enter your passcode: ");
String code = Scan.nextLine();
if (a.check(code) == true) {
System.out.println("logged in");
}
}
System.out.println("Employee does not exist!");
login();
}
I am doing the print statement in the for loop to see what it is findng, and unfortunalty it is only the first account
EDIT: I have included more code here, my after my initial if statement i want to check if the code the user enters is also correct.
see if the name of an employee matches one in the list then the if
statement continues, further questions asked etc... it seems to only
iterate once and then stop as it will only find the first user and
tell me the other accounts do not exisit, even though they do!!
If it works for one employee and tells that others don't exist then your for loop does not iterate once.
The output you get is exactly what the code looks like. You get username once then try to match the same name with every employee in the list. If the names are equal you ask for password, otherwise you print out that employee doesn't exist. Everything right as it is in the code. You should add to your question the expected behaviour so I, or someone else can fix your code without guessing the purpose of your methods.
Here's one of those guesses:
System.out.println("Please enter your name: ");
String empName = Scan.nextLine();
boolean userFound = false;
for (Account a : Accounts) {
System.out.println(a);
if (a.getname().equals(empName)) {
System.out.println("\nPlease enter your passcode: ");
String code = Scan.nextLine();
if (a.check(code) == true) {
System.out.println("logged in");
userFound = true;
break;
}
}
}
if(userFound) {
login();
} else {
System.out.println("User not found.");
}
This is a possible solution that doesn't use your Account class (since I do not know what it looks like) and instead uses a Map:
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
System.out.println("Hello welcome: ");
System.out.println("Please enter your name: ");
String empName = input.nextLine();
boolean found = false;
Map<String, String> accounts = new HashMap<String, String>();
accounts.put("Geoff", "password1");
accounts.put("Bob", "password2");
accounts.put("John", "password3");
Set<String> names = accounts.keySet();
for (String a : names)
{
if (!a.equals(empName))
{
continue;
}
found = true;
// three tries to login
boolean success = false;
for(int i = 0; i < 3; i++)
{
System.out.println("Please enter your passcode: ");
String code = input.nextLine();
if (accounts.get(a).equals(code))
{
System.out.println("logged in");
success = true;
}
else
{
System.out.println("Wrong password... try again");
}
}
if(!success)
{
System.out.println("User failed to authenticate after 3 attempts. User has been locked out!");
}
}
if(!found)
{
System.out.println("Employee does not exist!");
}
}
Since I do not know what the login() method does, I just simply added that into the code. This solution iterates three times in an attempt to get the correct password. If that fails, a message is displayed.

Filtering an arraylist using a method

I am trying to return a list of doctors who have a patient based on a date given by the user. But each time I run the method, it returns the list of all doctors instead of being filtered.
Code on Main
public void printDoctorsWithPatientsOnDate() throws ParseException
{
ArrayList<String> docs = new ArrayList();
System.out.print("Enter the date(mm-dd-yyyy): ");
Date dt = new SimpleDateFormat("MM-dd-yyyy").parse(sc.nextLine());
docs = app.getDoctorsWithPatientsOnDate(dt);
for(String i : docs)
{
System.out.println(i);
}
}
Method for filtering
public ArrayList<String> getDoctorsWithPatientsOnDate(Date date)
{
ArrayList<String> doctors = new ArrayList();
for(Patient i : patientList)
{
if(i.searchDatesForDoc(date) == true);
{
doctors.add(i.getDoctorName());
}
}
return doctors;
}
Method for searching the dates of a patient
public boolean searchDatesForDoc(Date date){
for(Date i : datesOfVisit)
{
if(i.equals(date))
{
return true;
}
}
return false;
}
I have initialized 2 patients namely patient1 and patient 2. patient1's doctor is named dr.lee and patient 2's doctor is named dr.james. first, i enter the following information for patient1 and i left patient2 with nothing(for now).
Enter the Patient's name: patient1
Enter the assessment: alz
Enter the date of Visit(mm-dd-yyyy): 10-02-2010
and the problem comes when I get the list of doctors. Even though the date is wrong, it keeps on printing the every doctor on the list.
Enter the date(mm-dd-yyyy): 11-20-2012
dr.lim
dr.james
For some unknown reason (to me anyway), the accepted answer that I gave was deleted by a moderator.
The problem has been resolved. The problem was that he had an extra semicolon after the if statement.
I don't have all the code to reproduce, but I would focus on the searchDatesForDoc method first. Try this:
public ArrayList<String> getDoctorsWithPatientsOnDate(Date date)
{
ArrayList<String> doctors = new ArrayList();
for(Patient i : patientList)
{
System.out.println("Current patient is: " + i.getPatientName());
if(i.searchDatesForDoc(date) == true);
{
doctors.add(i.getDoctorName());
}
}
return doctors;
}
public boolean searchDatesForDoc(Date date){
for(Date i : datesOfVisit)
{
if(i.equals(date))
{
System.out.println("\tVisited on day: " + i);
return true;
}
}
return false;
}
When you run with those two lines added, it will print the patient name followed with the days that the patient visited. First thing to check is whether or not the patient actually did visit on those dates listed. If not, then your problem is there. This would be a lot easier to debug with a debugger to trace through each step of your code.

Categories

Resources