Java: for loop and if algorithm

I have this question from a task for creating a store in which books are rented using Store.java and Book.java. I finished this task, but I'm interested in the best algorithm for a specific part.

-

Book.java

public class Book { private String name; Book(String name) this.name = name; public String getName() return name; } 

Store.java

Inside main ();

  Book bookObj[] = new Book[3]; //Create 3 Array of Object. bookObj[0] = new Book("Game Over"); bookObj[1] = new Book("Shrek"); bookObj[2] = new Book("Ghost"); Scanner console = new Scanner(System.in) input = console.nextLine(); 

Assuming input = Devil.

Now I need to do a simple search to check if a particular book exists.

Example:

  for(int i = 0; i < bookObj.length; i++) { if(bookObj[i].getName().equals(input)) System.out.println("Book Found!"); } 

Apparently, this is a for loop, which cycles through the array of the object and checks if such a Book exists. Now the problem arises when I want to conclude that the book was not found.

Example:

  for(int i = 0; i < bookObj.length; i++) { if(bookObj[i].getName().equals(input)) System.out.println("Book Found!"); else System.out.println("Book not Found!"); } 

The problem with the above code is that Book not Found will print three times. My goal is to avoid such a problem. I have solutions for this, but I'm still looking for the best to use, which uses getName (), which, in my opinion, still has room for improvement.

Usually in structural programming, I did the following:

 for(int i = 0; i < bookObj.length; i++) { if(bookObj[i].getName().equals(input)) System.out.println("Book Found!"); else if(i == bookObj.length - 1) System.out.println("Book not Found!"); } 

This is useful to determine if this cycle end has ended and the search has ended, but there was no search result.

How do I think of an object oriented way?

In general, my question is:

  • Is there a better way to write the code above rather than checking that this is the end of a line?
  • Is there a better way to use getName () method or to use other methods?
+4
source share
6 answers

You have to go through the array and use the index / boolean flag to store it regardless of whether the book is found. Then print the message at the end based on the index / flag value.

 int foundAtIndex = -1; for(int i = 0; i < bookObj.length; i++) { if(bookObj[i].getName().equals(input)) { foundAtIndex = i; // store the actual index for later use break; // no need to search further } } if(foundAtIndex >= 0) System.out.println("Book Found!"); else System.out.println("Book not Found!"); 

Alternatively (unless your job specifically requires an array), you should prefer Set , which can search for a single call to contains() .

How do I think of an object oriented way?

When looking at one method, the difference between procedural and OO style is small. Differences begin to appear at a higher level when trying to organize a bunch of conceptually related data and the methods that work on them.

The OO paradigm is to associate methods with the data on which they work, and encapsulate them in coherent objects and classes. These classes preferably represent important domain concepts. Therefore, for your bookstore, you can put all the code associated with the book in your Book class. However, the aforementioned search method (and the collection of books on which it works) is not associated with any particular copy of the book, so you have different options:

  • places both a collection of books and a search method in the Store (possibly as regular members) or
  • put them in the Book as static members.

The first choice is more natural, so I usually prefer this. However, under certain circumstances, the second option is preferable. In design (OO), there are almost always yes / no answers - rather a compromise between different options, each of which has its own strengths and weaknesses.

+6
source

You can enter a state and remember whether you found the book or not.

If you are not using Java 1.4 or earlier, you can also use the foreach loop syntax:

 boolean bookFound = false; for(Book currentBook : bookObj) { if(currentBook.getName().equals(input)) //TODO: see above } 

In addition, I would suggest looking into the Collection Library and replacing the array with a list or installing:

 Set<Book> books = new HashSet<Book>(); books.put(new Book("Game Over")); books.put(new Book("Shrek")); books.put(new Book("Ghost")); 

And, although they were in it, you might also think when the two books are equal and override equals () and hashCode () accordingly. If equal () is changed to check the title, you can simply use books.contains(new Book(input)); , and libraries will work for you.

+2
source

To solve the problem better, you must understand that the power of Java does not come from the language itself, but from the Java Framework.

You should study the use of Java Collection classes (never work with arrays again). Then you can solve the search with just one line of code:

 ArrayList<Book> listOfBooks; // init your list here listOfBooks.contains(new Book(input)); 

To do this, you also need to learn how to properly implement the equals () method of your Book class.

Happy learning!

+1
source

Here is a working solution:

 import java.util.Scanner; public class Store { private static class Book { private String name; Book(String name) { this.name = name; } public String getName() { return name; } } public static void main(String[] args) { String input; Book[] bookObj = new Book[3]; bookObj[0] = new Book("Game Over"); bookObj[1] = new Book("Shrek"); bookObj[2] = new Book("Ghost"); Scanner console = new Scanner(System.in); input = console.nextLine(); boolean found = false; int i = 0; while(!found && i < bookObj.length) { if(bookObj[i].getName().equals(input)) { System.out.println("Book Found at position : " + i); found = true; } else { i++; } } if(!found) { System.out.println("Book not Found!"); } // Here i contains the indice of the element found in the array. } } 
0
source

So far, you have received some pretty good advice. You asked if there is a more object-oriented way of thinking about a problem, so I thought that I would try to shed light on it. Since Peter has already mentioned at this level of design, this is the only implementation of the method, so the approach will be quite similar, such as the procedural approach. What is the advantage? In a word reuse. If you need to find a book by name in many places, moving your code to it will help your own class.

So, you have one copy of a book to encapsulate behavior around one book, but you want to have behavior across multiple books or a collection of books. You can store data (an array of books) and the method that their account shares, as you described in your program. However, if we wanted to gather a place for behavior in a collection of books, we can define a new class. Let me call it a library, and we can do something like the following:

 public class Library { private Book[] books; private bookCount = 0; public Library( int numberOfTotalBooks ) { books = new Book[numberOfTotalBooks]; } public boolean addBook( Book book ) { if( bookCount < book.length ) { books[bookCount++] = book; return true; } return false; } public Book findByTitle( String title ) { for( int i = 0; i < bookCount; i++ ) { if( books[i].getTitle().equals( title ) ) { return books[i]; } } // didn't find one return null; } } 

So, a few things to note that they do. Firstly, when we work with the library, we do not know that there is an array there. We could use an array, set, list, or database (the most common). The point, which is the code that calls these functions, works only with the library interface (and not with the literal Java interface, but with the signature of the library method). It is also a higher level interface. We are not worried about sorting through books, doing for loops, if statements, etc. We just call a method that says "Hey, find the name of this book in the Library." How this was done, we do not care. This is the main tenant of Object Orientation, called encapsulation, and deceptively powerful. It really is about how we delegate responsibility in our program and give details of work to an individual class or classes. If there were only public participants in the Library (i.e. Books and bookCount), or getter / setters, then the client would not receive any benefits, because the client would still have to complete the whole difficult climb. The trick for OO is that you can delegate from an object without creating problems. It requires practice and experience.

Secondly, we separated the presentation from the act of searching for a book. The method you wrote suggested the next step, which was to print "Hey, we found it." However, the library object simply returns you the book when it finds it, or null if it is not. This allows you to print to the console, display in the GUI, or serialize it to a JSON stream on the server. The act of searching for a book is separate from visualization. This is another important aspect of programming in general, but some of them are related to object orientation and encapsulation. This is usually called separation of concerns. The console application has problems with user interface support and console printing. Although the Library only manages cataloging and book collection management. How these details are carried out do not care.

At the end, the library is a reusable class. We can use it in a console application, desktop, network or intermediate server. Moreover, we can also reuse calls to findByTitle or addBooks from several places within the same program. In addition, by placing methods with data, we create a barrier to where this function can be used. You cannot do this in your program. You must have a link to the library. Unless you have a reference to a library instance, you should not call it. This can be unpleasant for new developers, because they lack the experience to properly organize their programs, so as not to get into trouble with this (then they start making value objects, creating statics, single games, etc., and everything turns in a big ball of mud). This is a double-barreled sword.

Another thing I would like to point out is to say that we would like to model two libraries. We have a library in the city center and in the city center, and we want people to be able to check books from the Library. With OO that are very easy to imagine:

 Library uptown = new Library( 50 ); Library downtown = new Library( 100 ); 

Now we can check books from one or the other. And I did not use statics (i.e. Global variables), so reusing this logic is very simple. These are the basics of OO, so they are really deep topics. It is strange how I can write so much on very simple topics. In any case, I hope this helps you understand your program a little deeper and see how you can use OO to help you.

0
source

chubbsondubs came closest to give the right answer to this question

What he missed is that his algorithm is incorrect, as it contains two tests when only one is required. The correct code requires only 3 operators and looks like this:

  public boolean zLibaryContains( String title ) { books[bookCount] = title; int xBook = 0; while( true ) if( books[xBook].getTitle().equals( title ) ) return xBook != bookCount; else xBook++; } 

Noticeably smaller and faster than all other solutions. Simplify, simplify, simplify.

Object-oriented code is a crutch to support poor designs that would otherwise be too complicated to understand. The goal is to write code that is so easy to understand and maintain that OO is unnecessary and will make the program worse. When your program can be improved by adding OO, it means that you start with something wrong.

-1
source

All Articles