5
\$\begingroup\$

A beginner level "Student Library Program" in Java, which interacts the Students and the Books. This Library Program can do following functions:

  1. Adding a Book to Library.

  2. Update Book Quantity.

  3. Search a Book with its Serial number.

  4. Search Books With Author Name.

  5. Show all Books and their related Information.

  6. Registering a Student.

  7. Show All Registered Students.

  8. Student can Check Out Book From Library (if registered).

    • Student can not Check Out max than 3 Books

    • You can only borrow a Book If it is Available in Library

  9. Student can Check In Book to Library.

  10. You can also see the Books which a Student has Checked Out(only while checking in)

Note: At the time it can store only 50 books for simplicity in program.

I have created this program to the best of my ability. I'm a beginner, so I couldn't do more.

package library;

import java.util.Scanner;



public class book {

public int sNo;
public String bookName;
public String authorName;
public int bookQty;
public int bookQtyCopy;

Scanner input = new Scanner(System.in);

public book(){

    System.out.println("Enter Serial No of Book:");
    this.sNo = input.nextInt();
    input.nextLine();
    System.out.println("Enter Book Name:");
    this.bookName = input.nextLine();
    System.out.println("Enter Author Name:");
    this.authorName = input.nextLine();
    System.out.println("Enter Quantity of Books:");
    this.bookQty = input.nextInt();
    bookQtyCopy = this.bookQty;

}

}

package library;

import java.util.Scanner;

public class books {

book theBooks[] = new book[50];     // Array that stores 'book' Objects.
public static int count;    // Counter for No of book objects Added in Array.

Scanner input = new Scanner(System.in);




public int compareBookObjects(book b1, book b2){

    if (b1.bookName.equalsIgnoreCase(b2.bookName)){

        System.out.println("Book of this Name Already Exists.");
        return 0;

    }
    if (b1.sNo==b2.sNo){

        System.out.println("Book of this Serial No Already Exists.");
        return 0;
    }
    return 1;
}

public void addBook(book b){

    for (int i=0; i<count; i++){

        if (this.compareBookObjects(b, this.theBooks[i]) == 0)
            return;

    }

    if (count<50){

        theBooks[count] = b;
        count++;

    }
    else{

        System.out.println("No Space to Add More Books.");

    }

}

public void searchBySno(){

    System.out.println("\t\t\t\tSEARCH BY SERIAL NUMBER\n");

    int sNo;
    System.out.println("Enter Serial No of Book:");
    sNo = input.nextInt();

    int flag = 0;
    System.out.println("S.No\t\tName\t\tAuthor\t\tAvailable Qty\t\tTotal Qty");
    for (int i=0; i<count; i++){

        if (sNo == theBooks[i].sNo){

            System.out.println(theBooks[i].sNo + "\t\t" + theBooks[i].bookName + "\t\t" + theBooks[i].authorName + "\t\t" + 
                theBooks[i].bookQtyCopy + "\t\t" + theBooks[i].bookQty);
            flag++;
            return;

        }

    }
    if (flag == 0)
        System.out.println("No Book for Serial No " + sNo + " Found.");

}

public void searchByAuthorName(){

    System.out.println("\t\t\t\tSEARCH BY AUTHOR'S NAME");
    input.nextLine();
    System.out.println("Enter Author Name:");
    String authorName = input.nextLine();
    int flag = 0;
    System.out.println("S.No\t\tName\t\tAuthor\t\tAvailable Qty\t\tTotal Qty");
    for (int i=0; i<count; i++){

        if (authorName.equalsIgnoreCase(theBooks[i].authorName)){

            System.out.println(theBooks[i].sNo + "\t\t" + theBooks[i].bookName + "\t\t" + theBooks[i].authorName + "\t\t" + 
                theBooks[i].bookQtyCopy + "\t\t" + theBooks[i].bookQty);
            flag++;
        }

    }
    if (flag == 0)
        System.out.println("No Books of " + authorName + " Found.");

}


public void showAllBooks(){

    System.out.println("\t\t\t\tSHOWING ALL BOOKS\n");
    System.out.println("S.No\t\tName\t\tAuthor\t\tAvailable Qty\t\tTotal Qty");
    for (int i=0; i<count; i++){

        System.out.println(theBooks[i].sNo + "\t\t" + theBooks[i].bookName + "\t\t" + theBooks[i].authorName + "\t\t" + 
                theBooks[i].bookQtyCopy + "\t\t" + theBooks[i].bookQty);


    }

}

public void upgradeBookQty(){

    System.out.println("\t\t\t\tUPGRADE QUANTITY OF A BOOK\n");
    System.out.println("Enter Serial No of Book");
    int sNo = input.nextInt();
    for (int i=0; i<count; i++){

        if (sNo == theBooks[i].sNo){

            System.out.println("Enter No of Books to be Added:");
            int addingQty = input.nextInt();
            theBooks[i].bookQty += addingQty;
            theBooks[i].bookQtyCopy += addingQty;
            return;

        }

    }

}


public void dispMenu(){

    System.out.println("----------------------------------------------------------------------------------------------------------");
    System.out.println("Enter 0 to Exit Application.");
    System.out.println("Enter 1 to Add new Book.");
    System.out.println("Enter 2 to Upgrade Quantity of a Book.");
    System.out.println("Enter 3 to Search a Book.");
    System.out.println("Enter 4 to Show All Books.");
    System.out.println("Enter 5 to Register Student.");
    System.out.println("Enter 6 to Show All Registered Students.");
    System.out.println("Enter 7 to Check Out Book. ");
    System.out.println("Enter 8 to Check In Book");
    System.out.println("------------------------------------------------------------- 
   ---------------------------------------------");

}

public int isAvailable(int sNo){

    //returns the index number if available



    for (int i=0; i<count; i++){

        if (sNo == theBooks[i].sNo){
            if(theBooks[i].bookQtyCopy > 0){

                System.out.println("Book is Available.");
                return i;

            }
            System.out.println("Book is Unavailable");
            return -1;

        }

    }

    System.out.println("No Book of Serial Number " + " Available in Library.");
    return -1;


}

public book checkOutBook(){

    System.out.println("Enter Serial No of Book to be Checked Out.");
    int sNo = input.nextInt();

    int bookIndex =isAvailable(sNo);

    if (bookIndex!=-1){

        //int bookIndex = isAvailable(sNo);
        theBooks[bookIndex].bookQtyCopy--;

        return theBooks[bookIndex];
    }

    return null;

}

public void checkInBook(book b){

    for (int i=0; i<count; i++){

        if (b.equals(theBooks[i]) ){

            theBooks[i].bookQtyCopy++;
            return;

        }

    }

}







 }

package library;

import java.util.Scanner;    
public class student {

String studentName;
String regNum;

book borrowedBooks[] = new book[3];
public int booksCount = 0;

Scanner input = new Scanner(System.in);

public student(){

    System.out.println("Enter Student Name:");
    this.studentName = input.nextLine();

    System.out.println("Enter Reg Number:");
    this.regNum = input.nextLine();

}
}

package library;

import java.util.Scanner;

public class students {

Scanner input = new Scanner(System.in);

student theStudents[] = new student[50];

//books book;


public static int count = 0;

public void addStudent(student s){

    for (int i=0; i<count; i++){

        if(s.regNum.equalsIgnoreCase(theStudents[i].regNum)){

            System.out.println("Student of Reg Num " + s.regNum + " is Already Registered.");
            return;
        }

    }

    if (count<=50){

        theStudents[count] = s;
        count++;

    }

}
public void showAllStudents(){

    System.out.println("Student Name\t\tReg Number");
    for (int i=0; i<count; i++){

        System.out.println(theStudents[i].studentName + "\t\t" + theStudents[i].regNum);

    }


}

public int isStudent(){
    //return index number of student if available

     //System.out.println("Enter Student Name:");
    //String studentName = input.nextLine();

    System.out.println("Enter Reg Number:");
    String regNum = input.nextLine();

    for (int i=0; i<count; i++){

        if (theStudents[i].regNum.equalsIgnoreCase(regNum)){

            return i;

        }

    }
    System.out.println("Student is not Registered.");
    System.out.println("Get Registered First.");


    return -1;

}
public void checkOutBook(books book){
    int studentIndex =this.isStudent();

    if (studentIndex!=-1){
        System.out.println("checking out");

        book.showAllBooks();//jjjjjjjjjjjj
        book b = book.checkOutBook();
        System.out.println("checking out");
        if (b!= null){

            if (theStudents[studentIndex].booksCount<=3){
                System.out.println("adding book");
                theStudents[studentIndex].borrowedBooks[theStudents[studentIndex].booksCount] = b;
                theStudents[studentIndex].booksCount++;
                return;

            }
            else {

                System.out.println("Student Can not Borrow more than 3 Books.");
                return;

            }
        }
        System.out.println("Book is not Available.");

    }

}

public void checkInBook(books book){

    int studentIndex = this.isStudent();
    if (studentIndex != -1){
        System.out.println("S.No\t\t\tBook Name\t\t\tAuthor Name");
        student s = theStudents[studentIndex];
        for (int i=0; i<s.booksCount; i++){

            System.out.println(s.borrowedBooks[i].sNo+ "\t\t\t" + s.borrowedBooks[i].bookName + "\t\t\t"+
                    s.borrowedBooks[i].authorName);

        }
        System.out.println("Enter Serial Number of Book to be Checked In:");
        int sNo = input.nextInt();
        for (int i=0; i<s.booksCount; i++){

            if (sNo == s.borrowedBooks[i].sNo){

                book.checkInBook(s.borrowedBooks[i]);
                s.borrowedBooks[i]=null;
                return;

            }


        }
        System.out.println("Book of Serial No "+sNo+"not Found");

    }



}


}

package library;

import java.util.Scanner;

public class Library {


public static void main(String[] args) {

    Scanner input = new Scanner(System.in);

    System.out.println("********************Welcome to the Student Library!********************");
    System.out.println("              Please Select From The Following Options:               ");
System.out.println("**********************************************************************");
    books ob = new books();
    students obStudent = new students();
    int choice;
    int searchChoice;

    do{

        ob.dispMenu();
        choice = input.nextInt();

        switch(choice){

            case 1:
                book b = new book();
                ob.addBook(b);
                break;

            case 2:
                ob.upgradeBookQty();
                break;

            case 3:
                System.out.println("Enter 1 to Search with Serial No.");
                System.out.println("Enter 2 to Search with Author Name(Full Name).");
                searchChoice = input.nextInt();

                switch(searchChoice){

                    case 1:
                        ob.searchBySno();
                        break;
                    case 2:
                        ob.searchByAuthorName();

                }
                break;

            case 4:
                ob.showAllBooks();
                break;
            case 5:
                student s = new student();
                obStudent.addStudent(s);
                break;
            case 6:
                obStudent.showAllStudents();
                break;
            case 7:
                obStudent.checkOutBook(ob);
                break;
            case 8:
                obStudent.checkInBook(ob);
                break;
            default:
                System.out.println("CHOICE SHOULD BE BETWEEN 0 TO 8.");

        }

    }
    while (choice!=0);
































}

}
\$\endgroup\$
1
8
\$\begingroup\$

In Java, class names should begin with a capital letter. So you should have

class Book { ... }
class Books { ... }
class Student { ... }
class Students { ... }

Each book has its own Scanner, as does books, every student, and students, and the Library. This is A Really Bad Idea™. A Scanner can buffer many, many characters that it has read from the underlying input stream but not presented to the caller. Having more than one Scanner can lead to strange behaviour, where it looks like the input is getting lost, or arriving in the wrong order. Having 103 scanners (one for each of the 50 book instances, one for each of the 50 student instances, plus one each for the books, students, and Library instances) will make scanner input issues virtually impossible to debug.

Create only one Scanner, in the Library class, and pass that instance to any method that needs to perform any reading.


book

The book class is a data model. It should just store information; it should not perform any I/O operations on the Console. Doing so prevents it from being used in a GUI application. If we remove the I/O, it could be used in a Console application or a GUI application without modification. Here is the Book class without any I/O:

class Book {
    public int    sNo;
    public String bookName;
    public String authorName;
    public int    bookQty;
    public int    bookQtyCopy;

    public Book(int no, String title, String author, int quantity) {
        sNo         = no;
        bookName    = title;
        authorName  = author;
        bookQty     = quantity;
        bookQtyCopy = bookQty;
    }
 }

The creator of a Book would need to get the book information from the user (such as reading from the Scanner), and only call new Book(...) once it has all the data.

You haven't used final anywhere in your code. If you have learnt it, consider that some of the Book fields should be final to prevent accidental changes.

You haven't used private anywhere in your code. You may want to make some fields private, and provide getters (and setters), instead of allowing public access to the fields.


books

public class books {
    book theBooks[] = new book[50];     // Array that stores 'book' Objects.
    public static int count;            // Counter for No of book objects Added in Array.

Why is count static? If you have two books objects (say, two libraries -- one on campus, one downtown), each would have its own theBooks array for storing the book objects that it owns. But there would only be one common count between the two. They would be required to have the same number of book objects, but the book objects could be completely different? That is seems like a design error.

compareBookObjects(): this function takes two books and returns ... what? What does 0 mean? What does 1 mean? If 0 is returned, a message is written to the console, but what if we wanted to create a GUI program and there is no console??? It is only used by addBook(), so is more of a helper function, and perhaps should be private. It is searching for a book title, and a book serial number. You have other functions which search for books by title and serial number, and finding them is not an indication of a duplicate error, but of a successful search. Maybe you need different helper functions, plural:

private Book findByTitle(String title) {
    for (int i=0; i<count; i++) {
        if (theBooks[I].bookName.equalsIgnoreCase(title)) {
            return book;
        }
    }
    return null;  // Not found
}

private Book findBySerialNo(int no) { ... }

The you could re-write addBook(...) like:

public void addBook(book b) {
    if (findByTitle(b.bookName) != null) {
        System.out.println("Book of this Name Already Exists.");
    }
    if (findBySerialNo(b.sNo) != null) {
        System.out.println("Book of this Serial No Already Exists.");
    }
    if (count < 50) {
       theBooks[count] = b;
       count++;
    } else {
       System.out.println("No Space to Add More Books.");
    }
}

Note: Again, I/O in the books class should be eschewed. books is another data model class, and shouldn't have any I/O. So, perhaps the above checks can be moved out of addBook and to the caller which creates the book. Then, the uniqueness of the book name / serial no can be tested even before creating the book object.

What is that magic number 50? Can we get rid of it? Sure!

    if (count < theBooks.length) {

Now, if you change the allocation length of theBooks, you won't have to find all occurrences of that value in the source and change them.

The flag in searchBySno() is completely unnecessary. If you find the book, you immediately return; the incremented flag value is unused. If you don't find the book, you won't have returned, so the test flag == 0 will always be true. You can get rid of flag, and use the findBySerialNo() we created above:

...
Book book = findBySerialNo(sNo);
if (book != null) {
   // Print the book info
} else {
   System.out.println("No Book for Serial No " + sNo + " Found.");
}

Similarly, upgradeBookQty() can use findBySerialNo() to avoid writing the search for serial number loop yet again.

dispMenu() absolutely does not belong in books. The menu is printed by a call in Library. The input is asked for in Library. The dispatch is done in Library. The dispMenu() would make much more sense if move to Library. Note that this is again moving I/O out of this data model. (You might begin to think this is a common theme.)

isAvailable(), checkOutBook(), again is searching for a book by serial number. Use the helper function.


student

Similar comments as book. Move I/O out of data model class.


students

Similar comments as books.

  • Move I/O out of data model
  • count should not be static
  • 50 should be theStudents.length
  • Add a findStudentByRegNum() helper function, remove search loop from other methods.
  • 3 should be theStudents[studentIndex].borrowedBooks.length ... wait ... what?

The student class should manage its own books! Consider:

theStudents[studentIndex].borrowedBooks[theStudents[studentIndex].booksCount] = b;

You are referencing theStudents[studentIndex] twice in that statement, to get to the same student instance's borrowedBooks and bookCount fields. Instead, imagine finding the student, and telling that student to add the book to its list.

student s = findStudentByRegNum(reg_num);
s.addBook(b);

And the student class would do:

borrowedBooks[ bookCount ] = b;
bookCount++;

As well as first checking whether it is allowed to borrow another book:

if (booksCount < borrowedBooks.length) { ... } else { ... }

BUGS

  • Checking out the 4th book will cause an ArrayIndexOutOfBoundsException.
  • After a student has checked out 3 books, even after they have returned all 3 books, they can never check out another book, because booksCounts is never decremented.
  • If a student tried to check out a book, and fails due to too many borrowed books, the book is lost (quantity has already been decremented in the library).
\$\endgroup\$
1
  • \$\begingroup\$ Thank you so much Sir. your answer is very helpful for me and really meant to me. you helped me alot in understanding these problems which i never considered tysm \$\endgroup\$ – Kh Ahmed Nov 2 '18 at 9:11

Not the answer you're looking for? Browse other questions tagged or ask your own question.