Having trouble with for each loop - java

So I am trying to make this swing GUI that searches a list of books and then displays the book in a JTextArea. Here is my actionPerformed Method
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Search Books")){
String bookName = JOptionPane.showInputDialog(this, "Enter books to search"); // prompts user to enter book title
if (bookName == null){
sArea.append("Enter a Book");
}else{
for (Book b: ban.getListOfBooks()){ //going through list of books to find matching title
if (bookName.equals(b.getTitle())){ // appends string if it is equal to one of the book names
sArea.append(bookName);
}else{
sArea.append("Book not found");
}
}
}
}else{
...
So my problem is for the for each loop. Naturally it will print "Book not found" for every element in the list that is not equal. So if i have ten books, and i enter the name of the first one, it will print that and then "Book not found" nine times. How could i reformat this to only print out one thing?

You can use a boolean found flag and then check if the book was found at the end of the loop
}else{
boolean found = false;
for (Book b: ban.getListOfBooks()){ //going through list of books to find matching title
if (bookName.equals(b.getTitle())){ // appends string if it is equal to one of the book names
sArea.append(bookName);
found = true;
}else{
}
}
if (!found) sArea.append("Book not found");
}

If you want to still continue using foreach loop you can extract that part to a function, return the book name when it matches but if any book does not matche return "Not found" instead of appending every iterarion
Like this:
public String searchBook(List<Book> books, bookName ){
for (Book b: books)){ //going through list of books to find matching title
if (bookName.equals(b.getTitle())){
return b.getTitle();
}
}
return "Book not found"; }
So you just calling this function instead of your foreach loop like this:
sArea.append(this.searchBook(ban.getListOfBooks() , bookName))
It´s cleaner.
Finally I'm not sure if is correct to use append method If you just want to put the result everytime the user search.
Also if you have a List you can use indexOf or contains methods to know if a element exists in the list, it´s cleaner.
This can help you more : https://www.baeldung.com/find-list-element-java

Related

Iterate object arraylist with if condition

I'm a newbie of Java. I have a problem with object ArrayList that cannot iterate until the end when it doesn't catch up with If condition. In this code, if I input the second movie name and check for 'If condition', this condition doesn't iterate till the end. Seems like 'If condition' works for the first object value of ArrayList. Please someone points out to me what's wrong with this. Thanks in advances!
Here is the code:
boolean isFound=false;
for (Movies item: movie_list) {
if(item!=null && item.getMovie_name().contains(movie_name)) {
System.out.println("Movie exist");
isFound=true;
break;
}
}
if (!isFound) {
System.out.println("Movie doesn't exist!");
}
}

Java: if conditions setting

I am trying to run a getBook() method in a Bookstore program which can allow me to find a book stored in the AL books not only if title and author are correct but also if one of them is null.
So, I wrote this code:
public Book getBook(String author, String title){
boolean condOk = false;
Book book = null;
if(books!=null){
for(int i=0; i<books.size(); i++){
if((author==null && title.equals(books.get(i).getTitle())) ||
(author.equals(books.get(i).getAuthor()) && title==null)){
condOk = true;
book = books.get(i);
break;
} else if(title.equals(books.get(i).getTitle()) &&
author.equals(books.get(i).getAuthor())){
condOk = true;
book = books.get(i);
break;
}
}
}
if(condOk==false) return null;
else return book;
}
The J-Unit test (not created by me) of this part, puts in books 4 objects (with constructor: String title, String author, ...) and then it tests the method getBook() three times: with author and title, with title expressed and author null, and a last time with the opposite situation.
I have already tried something and I noticed that if I substitute all the equals() calls with the logical op == everything works fine.
In the Book class everything is correct, all the getters and setters are in the right place.
So, why do I get such a behavior, when several times I read that comparing Strings with equals() is better than doing it with ==?
You run into a NullPointerException, for example if title is null and author is not equal to a book in the list. The condition of the first if is false, so you enter the else part and the condition of the second if cannot be evaluated because in title.equals(books.get(i).getTitle()) the title is null.
This does not happen if you use ==, it is allowed to compare null values with ==.

Second record doesnt get stored in arraylist

I have an arraylist which the records are stored as objects.
In a different form i allow the user to enter an id and retrieve the data of that record with the corresponding id.
My problem is , i can only retrieve one record , meaning only the first record which i store in the arraylist.
If i type in a second record and if try to search the record using the id , i get the message "invalid id", its the message which i assigned to make sure that users won't enter invalid ids.
Here is the code which i used to store the object in to the arraylist:-
patient_class patients=new patient_class(firstname,lastname,initials,gender,birthday,birthmonth,birthyear,contactnumber,address,bloodgroup,patientid);
patientlist.add(patients);
Here is my code to check whether if the arraylist contains the id.
public boolean checkrecord(ArrayList<patient_class>patients,String search)
{
for(patient_class patient : patients)
{
if(patient.getid().contains(search))
{
return true;
}
}
return false;
}
if the it is true i have the created a separate constructor to find the record for the give id.
Here is the code for that :-
public patient_class searchrecord(ArrayList<patient_class> patients, String search)
{
for(patient_class patient: patients) //used enhanced for loop
if(patient.getid().equals(search))
{
return patient;
}
else
{
return null;
}
return null;
}
Why can i only enter one record but not 2 records in to the arraylist ? My program display "succussfuly registered" when i enter the second record and click register, but i cant search that record , but i can delete the record using another method i made.
What am doing wrong ?
This is the problem:
for(patient_class patient: patients) //used enhanced for loop
if(patient.getid().equals(search))
{
return patient;
}
else
{
return null;
}
return null;
Due to your else block, you're returning null if the first patient doesn't match the patient you're looking for, instead of looking for other matches. You should get rid of the else block. I'd also add braces to make the control flow clearer:
for (patient_class patient : patients) {
if (patient.getid().equals(search)) {
return patient;
}
}
// Only return null if we've checked *all* patients
return null;
Additionally, I'd strongly advise you to start following Java naming conventions, renaming patient_class to Patient and the getid method to getId:
for (Patient patient : patients) {
if (patient.getId().equals(search)) {
return patient;
}
}
return null;

Searching a Java LinkedList

I am trying to search through a Java LinkedList that uses a custom object called Name. I need to search on first name (My compareTo method in Name already compares last names because I need to use it to sort by last name). Name has an observer method called getFirstName().
I am not having any success in accessing first name from my LinkedList. This is what I want to do but this (obviously) doesn't work.
if (iterator.next().getFirstName().equals(inputSearch))
Can someone point me in the right direction?
This is the full method I am currently trying to write:
// Creating a method to search for a first name
static void searchName()
{
Scanner inData = new Scanner(System.in);
// Label to request input from user
System.out.println("Enter the first name that you would like to search for:");
// Setting variable to capture input
String inputSearch = inData.next();
// Creating an iterator to search through the list
iterator = list.iterator();
// While loop to search each entry
while (iterator.hasNext())
{
if (iterator.next().getFirstName().equals(inputSearch))
{
System.out.println("MATCH FOUND: " + iterator.next());
}
}
}
You're calling iterator.next() twice. The second time will advance past the item you want. Instead, save the return value from the first call to iterator.next() and use that.
while (iterator.hasNext())
{
Name item = (Name) iterator.next();
if (item.getFirstName().equals(inputSearch))
{
System.out.println("MATCH FOUND: " + item);
}
}
or, more idiomatically
for (Name item : list)
{
if (item.getFirstName().equals...
}
while (iterator.hasNext()) {
if (iterator.next().getFirstName().equals(inputSearch)) { //iterator.next()
System.out.println("MATCH FOUND: " + iterator.next()); //iterator.next()
}
}
Since you are calling next() twice, while printing it would be next object.
try storing whatever iterator.next() returns in its corresponding type and use it to compare and print if succeed.
ex:
while(iterator.hasNext(){
Name name=iterator.next();
if(name.getFirstName().equals(inputSearch)){
System.out.println("Match Found"+name);
}
}
This is what I see wrong. Not aware of anything else.

Creating a user friendly interface using an if statement in Java

I don't wish to leave a user stranded by returning nothing. Normally I can rectify this problem using a simple if else statement but since it's nested inside a for loop I don't get very good result. Below is my code for returning students attached to a module:
System.out.print("Search for a student: ");
scan = new Scanner(System.in);
String searchStudent = scan.nextLine().trim();
for (Student student : students) {
if (searchStudent.equalsIgnoreCase(student.getName())) {
Iterator it = modules.iterator();
Boolean found = false;
while (it.hasNext() && !found) {
Module module = (Module) it.next();
if (module.getStudents().contains(student)) {
System.out.printf("%s ", module.getName());
found = true;
}
}
} else {
System.out.println("Sorry. " + searchStudent + " does not exist in the database");
}
}
The output:
Search for a student: jane
UFCE3 UFCE1 Sorry. jane does not exist in the database
Sorry. jane does not exist in the database
Sorry. jane does not exist in the database
Sorry. jane does not exist in the database
Clearly in this example, Jane does exist in the database and she is enrolled on UFCE3 and UFCE1.
Since the if statement is nested inside the for loop I wouldn't expect anything less than getting an inaccurate output as the for loop will continue to loop until all elements in the student array have been passed. Any advice?
You can add a simple sentinel value (boolean flag) to your while statement. You start the value off as false, and then change it to true when a record is found.
Boolean found = false;
while (it.hasNext() && !found) {
Module module = (Module) it.next();
if (module.getStudents().contains(student)) {
System.out.printf("%s ", module.getName());
found = true;
}
Or you could use a "break" statement to terminate the loop.
while (it.hasNext() ) {
Module module = (Module) it.next();
if (module.getStudents().contains(student)) {
System.out.printf("%s ", module.getName());
break;
}
extract your for loop into a method, returning the modules you are interested in.
then call that method. check if you get any useful result and print it or print your excuse otherwise.
This is known as seperation of concerns. An entity should do exactly one thig. your for loop does at least three:
searching for students
searching for modules
printing results

Categories