Iterate object arraylist with if condition - java

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!");
}
}

Related

How could I refactor this bit of code here to achieve the same result?

I am working on an app for school. I was looking through the code and found this thing I made:
if (answerTxt1.getText().toString().matches("")) {
infoStatus.setText("Answer1 cannot be empty!");
return;
} else if (answerTxt2.getText().toString().matches("")){
infoStatus.setText("Answer2 cannot be empty!");
return;
} else if (answerTxt3.getText().toString().matches("")){
infoStatus.setText("Answer3 cannot be empty!");
return;
} else if (answerTxt4.getText().toString().matches("")){
infoStatus.setText("Answer4 cannot be empty!");
return;
}
The idea behind this 'logic' is that there are 4 slots to write on the app but none can't be empty. If one of them is empty, a textView named infoStatus will display the message about the Exception ocurred.
I know this can have a refactor and can be done in less lines but I am not sure how. So far my idea was this:
if (answerTxt1.getText().toString().matches("")
|| answerTxt2.getText().toString().matches("")
|| answerTxt3.getText().toString().matches("")
|| answerTxt4.getText().toString().matches("")) {
infoStatus.setText("One of the answers is empty!");
return;
}
but I won't get the specific message for the user of which answerTxt# is empty.
You can do it as
TextView[] textViews = {answerTxt1, answerTxt2, answerTxt3, answerTxt1};
for(int i=0; i<textViews.length; i++){
if(textViews[i].getText().toString().isEmpty()){
infoStatus.setText("Answer"+ (i+1) + " cannot be empty!");
break;
}
}
If you define a method that checks if an arbitrary text view is empty, and sets the error field if it is, like this:
boolean checkEmpty(TextView textView, String name) {
if (textView.getText().length() == 0) {
infoStatus.setText(name + " cannot be empty!");
return true;
}
return false;
}
Then you can get rid of most of the duplication in your code:
if (checkEmpty(answerTxt1, "answerTxt1")) {
return;
}
if (checkEmpty(answerTxt2, "answerTxt2")) {
return;
}
...
You can go even further by creating data structures to hold your text views and error messages, but it will come with the cost of making the code more complex, rigid, and brittle.

Having trouble with for each loop

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

throwing an exception and continuing to receive data

In a piece of code I'm currently working on, I'm taking in an ArrayList of data to be added to an object, from a user. I'm checking each item in the ArrayList against the current list of that type of data for the object, in order to make sure it's not in the list already.
Is there a way to throw an exception for one item in the passed- in list, to tell the user it's in the list already- and then to keep going and add the next items in the passed-in list to my current list if they aren't there already?
Update: i solved the problem by surrounding that block of code with a try/catch. Here's my code to clarify:
public void addCategories(ArrayList<BookCategory>categories) {
boolean exists;
for(int index = 0; index <categories.size(); index++) {//iterate through passed array list
try {
//for each element, check if it exists in the current category list.
exists = checkBookCategory(categories.get(index));
if (exists == false)
{subjectCategories.add(categories.get(index));}
else {
throw new IllegalArgumentException("Item " + categories.get(index) + " already in list."); }
}catch(IllegalArgumentException ie) {
System.out.println(ie);
} }
}
Thanks #JimGarrison!
The short answer is that yes, you can do this, but it usually is highly discouraged.
Some sample pseudocode:
for (Item i : inputList)
{
try
{
myObject.addItem(i);
}
catch (MyCustomDuplicateItemException ex)
{
// Tell the user there was a duplicate
}
}
However, this is using exceptions for what should be flow control. Ideally you would write the addItem() method to return a boolean value (i.e. true) if the item was successfully added, and the other value (false) if the item was a duplicate and NOT throw an exception.

Can't get string comparison right

I need help with my code below, I cant get the string comparison right with regards to the deleteNode method.
I searched StackOverflow and How do I compare strings in Java? was helpful, especially with Objects.equals.
However, running the method falls through all if statements, and the item never gets deleted. PS, excuse my English, not native speaker.
My code:
public void deleteNode(String clientAddr) {
boolean isFound = false;
for (ClientNode client : srv.connections) {
if (Objects.equals(client.getIpAddr(), clientAddr)) {
isFound = true;
srv.connections.remove(clientAddr);
break;
}
}
if (!isFound) {
System.out.println("Provided address is not found!");
System.exit(0);
}
}
Above is called via:
starNetwork.deleteNode("10.10.10.3");
If I for instance run the following:
public void deleteNode(String clientAddr) {
for (ClientNode client : srv.connections) {
System.out.println(Objects.equals(client.getIpAddr(), clientAddr));
}
}
it outputs:
false
true
false
I don't understand
You check just the first element and exit the program if its not found.
Instead try looping for the rest of the elements.
Also, you can't use remove() in a list of Object (of type ClientNode) and pass a String.
This means you're trying to compare a ClientNode Object with a String, which is not possible. So List is not removing any elements.
Recommend to use Iterators in such scenarios.
Change:
for (ClientNode client : srv.connections) {
if (Objects.equals(client.getIpAddr(), clientAddr)) {
srv.connections.remove(clientAddr);
} else {
System.out.println("Provided address is not found!");
System.exit(0);
}
}
To Something like:
boolean isFound = false;
for (Iterator<ClientNode> iterator = srv.connections.iterator(); iterator.hasNext();) {
ClientNode client = iterator.next();
if (Objects.equals(client.getIpAddr(), clientAddr)) {
isFound = true;
iterator.remove();
break;
}
}
if(!isFound) {
System.out.println("Provided address is not found!");
System.exit(0);
}
If you don't want to use a flag, then on first if condition write a return;
outside the loop blindly write a System.out.println("Provided address is not
found!");
Question has been answered with help from user Bandi Kishore below.
My deleteNode() method was not dealing with the right types, and was fixed with the help of an iterator.

Searching an array list for an item, then printing out something

I have been working on an exercise summarized as follows:
Write a program to store details of food items in a single array by using inheritance and polymorphism. Example, details of pizzas(item number, size, base), softdrinks(...)...
I have modeled everything, created my base class and derived classes.
Everything works fine except for one thing: when the user chooses to delete an item, I am supposed to output the string "Not found" if the item number is not found. My array list has each food item object (the subclasses) as elements. Here is my code for deleting an item from the array:
System.out.println("Enter the menu item number");
String num = input.next();
for(int j=0; j<menuItems.size();j++) //menuItems is my arraylist
{ if((menuItems.get(j).getItemNumber().equals(num))) //getItemNumber is a method in the derived class
menuItems.remove(j);
}
System.out.println("Done");
break; //for the switch statement
I am supposed to output "Not found" instead of "Done" if the item is not found in the array list. My initial attempt was as follows:
if(!menuItems.get(j).getItemNumber().contains(num))
System.out.println("Not found");
else
//the code above
This did not work because it is within the for-loop and the if-statement will check the array list even after the item has been removed. So, it will still evaluate to true.
Could someone please help me with this?
UPDATE:
I solved the problem as follows
int found=0; // element not found found =0 else 1
for(j=0; j<menuItems.size();j++)
{
if((menuItems.get(j).getItemNumber().equals(num)))
{
menuItems.remove(j);
System.out.println("Done");
found+=1;
}
}
if (found ==0)
{
System.out.println("Not found");
}
break; //for the switch statement
You could do it something like this
boolean found = false;
for(int j=0; j<menuItems.size();j++){
if((menuItems.get(j).getItemNumber().equals(num))){
menuItems.remove(j);
found = true;
break;
}
}
if(found){
System.out.println("Done");
} else {
System.out.println("Not found");
}
If you didn't manage to remove the item, then it wasn't there.
If you find and remove the element, break the switch (plates is just a random label):
plates: switch (smth) { //whatever you use here (not provided in the post)
...
for(int j=0; j<menuItems.size();j++) { //menuItems is my arraylist
if(menuItems.get(j).getItemNumber().equals(num)) { //getItemNumber is a method in the derived class
menuItems.remove(j);
System.out.println("Done!");
break plates; //for the switch statement
}
}
System.out.println("Not found!");
break; //for the switch statement (that you did not provide)
...
} //end of switch (if num is found, you continue from here)
I think maybe you can look at HashMap, then you can write your code like:
HashMap<String, Food> = new Hashmap<>();
String num = input.next();
final Food temp = MyMap.get(num)
if(temp == null)
{
//not found
}
else
{
//found
}

Categories