I'm new at java so sorry for the inconsistencies.
I'm creating a library program and I'm having trouble calling a method from the Book class in the Patron class.
In the Patron class I have a method checkOutBook() which a user can input a book to check out. However I'm having trouble accessing the setStatus() method in Book. I know I have to call it against an instance of the Book class but I'm unsure how to do so with a user inputed string.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class Book implements BookInterface {
Scanner input = new Scanner(System.in);
static ArrayList < String > UserList = new ArrayList < String > ();
static ArrayList < String > BookList = new ArrayList < String > ();
public String title;
public String author;
public Book book;
private String status;
private String borrower;
public Book(String t, String a) {
title = t;
author = a;
}
//constructor create new book
public Book(String newTitle) {
title = newTitle;
}
public String toString() {
return title + " " + author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getStatus(String book) {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public void setBorrower(String borrower) {
this.borrower = borrower;
}
public String getBorrower(String checkPatron) {
return borrower;
}
public String getBook(String checkPatron) {
return book;
}
public void setBook(Book bookCheckOut) {
this.book = bookCheckOut;
}
}
public void CheckOutBook() {
Scanner inputread = new Scanner(System.in);
Scanner input = new Scanner(System.in);
System.out.println("Enter full patron name: ");
String borrower = inputread.nextLine();
System.out.println("Enter book title to check out: ");
String bookCheckOut = inputread.nextLine();
if (Book.BookList.contains(bookCheckOut)) {
Book.BookList.remove(bookCheckOut);
Book.setStatus("OUT"); //error message
Book.setBorrower(borrower); //error message
System.out.println("----------" + bookCheckOut + " has been checked out!----------");
System.out.println("-------------------BOOK STATUS:---------------------");
System.out.println("Book Title: " + bookCheckOut);
System.out.println("Book Status: Checked out");
System.out.println("Borrower: " + borrower);
System.out.println("Due Date: " + dueDate);
System.out.println("----------------------------------------------------");
I attempted to do this but it didn't work either :(
Thank you for your help!
Book bookCheckOut = new Book(bookCheckOut); //error: constructor Book(book) undefined
bookCheckOut.setStatus("OUT");
bookCheckOut.setBorrower(borrower);
bookCheckOut.setBook(bookCheckOut);
Book bookCheckOut = new Book(bookCheckOut); <~ I think you are getting confused because you already defined bookCheckOut as a String from the scanner and in this line you are setting it to a book object. Try changing the first bookCheckOut in this line to something else. Syntax: Book bookObjectName = new Book("String");
For the setStatus and setBorrower error you are trying to use those methods as if they were static. To fix this don't call Book.setStatus but replace Book with your instantiated book object name. Example: Book b = new Book ("Asd","abc"); b.setStatus("xyz");
Also, why do have two scanners?
Change Book.BookList from ArrayList<String> to Map<String, Book> as shown below:
public class Book {
static Map<String, Book> BookList = new HashMap<>();
...
Then in CheckOutBook() change:
if (Book.BookList.contains(bookCheckOut)) {
Book.BookList.remove(bookCheckOut);
Book.setStatus("OUT"); //error message
Book.setBorrower(borrower); //error message
...
To:
Book book = Book.BookList.get(bookCheckOut);
if (book != null) {
Book.BookList.remove(bookCheckOut);
book.setStatus("OUT");
book.setBorrower(borrower);
...
Related
So I need to create 3 classes "Book"(with fields author, title and body, as string), "Shelf"(with fields id (string) and books (array) and "Library". Then I shall create a method "countAuthor".which counts (and returns as an int) the number of books in the library written by an author whose name (String) is passed as an argument to the method:
class Book {
private String author;
public String getAuthor() {return author;}
private String title;
public String getTitle() {return title;}
private String body;
public String getBody() {return body;}
}
class Shelf {
private String id;
public String getId() {return id;}
private int[] books;
public int[] getBooks() {return books;}
}
class Library {
private int[] shelves;
public int[] getShelves() {return shelves;}
public int countAuthor(String authorName) { // returns the number of books in the library written by author whose name (String)
//is passed as an argument to the method.
int a = ;
return a; // a is the number of books of the author
}
}
After all, in the class (where the main method is stated), I need to add the necessary code and the program overall shall print the number of books an author has written. This is the class of the main method:
public class Exercise {
public static void main(String[] args) {
Shelf shelf1 = new Shelf("Shelf1",
new Book[] {
new Book("Babel", "Odessa Tales", "babelode"),
new Book("Joyce", "Ulisses", "joyceuli")
});
Shelf shelf2 = new Shelf("Shelf2",
new Book[] {
new Book("Mann", "Dr Faustus", "mannfau"),
new Book("Babel", "Red Cavalry", "babelred")
});
Library lib = new Library(
new Shelf[] { shelf1, shelf2 });
System.out.println("# of books by this author: " + lib.countAuthor("Babel"));
}
}
Which should print # of book by this author: 2
Where I am confused with is what to add to the countAuthor() method. And if I need anything in addition to the method. I am pretty new to Java so I still get confused with some structures, especially with the loops.
Here it is. In your code you are missing constructors that you are trying to use so I added them. The logic of counting the books is just go through all the shelves in the lib and count all the books on these shelves with the author name.
public class Exercise {
public static void main(String[] args) {
Shelf shelf1 = new Shelf("Shelf1", new Book[]{
new Book("Babel", "Odessa Tales", "babelode"),
new Book("Joyce", "Ulisses", "joyceuli")});
Shelf shelf2 = new Shelf("Shelf2",
new Book[]{
new Book("Mann", "Dr Faustus", "mannfau"),
new Book("Babel", "Red Cavalry", "babelred")
});
Library lib = new Library(new Shelf[]{shelf1, shelf2});
System.out.println("# of books by this author: " + lib.countAuthor("Babel"));
}
}
class Book {
public Book(String author, String title, String body) {
this.author = author;
this.title = title;
this.body = body;
}
private String author;
public String getAuthor() {
return author;
}
private String title;
public String getTitle() {
return title;
}
private String body;
public String getBody() {
return body;
}
}
class Shelf {
public Shelf(String id, Book[] books) {
this.id = id;
this.books = books;
}
private String id;
public String getId() {
return id;
}
private Book[] books;
public Book[] getBooks() {
return books;
}
}
class Library {
public Library(Shelf[] shelves) {
this.shelves = shelves;
}
private Shelf[] shelves;
public Shelf[] getShelves() {
return shelves;
}
public int countAuthor(
String authorName) { // returns the number of books in the library written by author whose name (String)
//is passed as an argument to the method.
int count = 0;
for (Shelf shelf : shelves) {
for (Book book : shelf.getBooks()) {
if (book.getAuthor().equals(authorName)) {
count++;
}
}
}
return count; // a is the number of books of the author
}
}
Output:
# of books by this author: 2
As I can see from your question, the structure will be like this.
Library can have many Shelf and in every Shelf there are many books.
So to count the no of books for a particular author, first you need all the books.
It will be something like this.
public int countAuthor(String author) {
int result = 0;
for(Shelf shelf : shelves) {
for(Book book : shelf.getBooks()) {
if(author.equals(book.getAuthor()) {
result++;
}
}
}
return result;
}
import java.util.Arrays;
import java.util.Scanner;
public class employee{
public String name;
public class employee_address{
String street_name;
String city;
String zipcode;
String state;
String country;
}
public static void main(String []args){
Scanner user_input = new Scanner(System.in);
int no_of_employees = user_input.nextInt();
employee[] employees_list = new employee[no_of_employees];
for(int i = 0;i < no_of_employees;i++){
employees_list[i].name = user_input.nextLine();
employees_list[I].employee_address = // this is it ?
}
}
}
In the code above I do understand that the employee_address is a class and can't be accessed
directly without an instance being created like in the code, that makes no sense. but how can I create an instance of the employee_address class that is associate with each employee.
like in the code above 'employee_address' is associated with every employee but how can the class 'employee_address' be initialised and how can I set the street_name, city and the rest of the members in the address class. any ideas would be appreciated.
You can't directly create an instance of inner class, the reason because since it is the property of another instance we always need to use it though the instance of parent variable.
Let's say you have a class, which have two propeties:
public class Employee {
public String name;
public EmployeeAddress emAddress;
}
to access emAddress you need to use through the instance of Employee class, for example -
Employee object = new Employee();
EmployeeAddress empAdd = object.new EmployeeAddress();
Full code:
public class Employee {
public String name;
public EmployeeAddress emAddress;
public class EmployeeAddress {
String street_name;
String city;
String zipcode;
String state;
String country;
public String getStreet_name() {
return street_name;
}
public void setStreet_name(String street_name) {
this.street_name = street_name;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
#Override
public String toString() {
return "EmployeeAddress [street_name=" + street_name + ", city=" + city + ", zipcode=" + zipcode
+ ", state=" + state + ", country=" + country + "]";
}
}
public static void main(String[] args) {
Scanner user_input = new Scanner(System.in);
int no_of_employees = user_input.nextInt(); // let's say no_of_employees = 1
Employee[] employees = new Employee[no_of_employees];
for (int i = 0; i < no_of_employees; i++) {
Employee object = new Employee();
object.setName("Virat Kohli");
EmployeeAddress empAdd = object.new EmployeeAddress();
empAdd.setCity("New Delhi");
empAdd.setCountry("India");
empAdd.setState("Delhi");
empAdd.setStreet_name("Chandni Chalk");
empAdd.setZipcode("741124");
object.setEmAddress(emAddress);
employees[i] = object;
}
System.out.println(employees[0]);
user_input.close();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public EmployeeAddress getEmAddress() {
return emAddress;
}
#Override
public String toString() {
return "Employee [name=" + name + ", emAddress=" + emAddress + "]";
}
public void setEmAddress(EmployeeAddress emAddress) {
this.emAddress = emAddress;
}
}
I have modified your code to sonar standard.
Below code uses Java naming conventions (which your code does not).
Notes after the code.
import java.util.Scanner;
public class Employee {
private String name;
private EmployeeAddress address;
public class EmployeeAddress {
String streetName;
String city;
String zipcode;
String state;
String country;
}
public static void main(String[] args) {
Scanner userInput = new Scanner(System.in);
int noOfEmployees = userInput.nextInt();
Employee[] employeesList = new Employee[noOfEmployees];
for (int i = 0; i < noOfEmployees; i++) {
employeesList[i] = new Employee();
employeesList[i].name = userInput.nextLine();
EmployeeAddress employeeAddress = employeesList[i].new EmployeeAddress();
employeesList[i].address = employeeAddress;
employeesList[i].address.streetName = userInput.nextLine();
}
}
}
An inner class is a normal class. It is not a member of its enclosing class. If you want class Employee to have an [employee] address, as well as a [employee] name, you need to add another member variable to class Employee whose type is EmployeeAdress.
Employee[] employeesList = new Employee[noOfEmployees];
The above line creates an array but every element in the array is null. Hence you need to first create a Employee object and assign it to an element of the array. Hence the following line in my code, above:
employeesList[i] = new Employee();
Since EmployeeAddress is not a static class, in order to create a new instance, you first need an instance of the enclosing class, i.e. Employee. Hence the following line in the above code.
EmployeeAddress employeeAddress = employeesList[i].new EmployeeAddress();
Since all your code is in class Employee, in method main you can directly access the members of both class Employee and EmployeeAddress. Nonetheless you need to be aware of the different access modifiers in java.
A few hints:
stick to naming conventions: class names in Java start with capital letters
use (class) definitions before using them (collect them at the top if not inconventient)
if you are sure you want to use inner classes, set them static, unless you want them to be entangled in generics.
Usually normal classes in each their own file are a lot more flexible and far easier to use
if you use objects that only carry public data, try to use final keyword and initialize them ASAP
use proper objects first, and after finishing them assign them to arrays. avan better would be the use of ArrayList and the like
if Employee contains EmployeeAddress, it should initialize it if conventient. so an object is always responsible for its own stuff
Use try/resrouce/catch
scanner.nextInt() can be problematic with newline/line breaks. For user input better readLine() and parse input
Code:
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Scanner;
public class Employee {
static public class EmployeeAddress {
public final String street_name;
public final String city;
public final String zipcode;
public final String state;
public final String country;
public EmployeeAddress(final Scanner pScanner, final PrintStream pOutPS) {
street_name = readLine(pScanner, pOutPS, "Please enter Street Name:");
city = readLine(pScanner, pOutPS, "Please enter City Name:");
zipcode = readLine(pScanner, pOutPS, "Please enter Zip Code:");
state = readLine(pScanner, pOutPS, "Please enter State:");
country = readLine(pScanner, pOutPS, "Please enter Country:");
}
}
static public String readLine(final Scanner pScanner, final PrintStream pOutPS, final String pPrompt) {
pOutPS.print(pPrompt);
final String value = pScanner.nextLine();
pOutPS.println();
return value;
}
static public int readInt(final Scanner pScanner, final PrintStream pOutPS, final String pPrompt) {
return Integer.parseInt(readLine(pScanner, pOutPS, pPrompt));
}
public final String name;
public final EmployeeAddress address;
public Employee(final Scanner pScanner, final PrintStream pOutPS) {
name = readLine(pScanner, pOutPS, "Please enter Employee Name: ");
System.out.println("Name: " + name);
address = new EmployeeAddress(pScanner, pOutPS);
}
public static void main(final String[] args) {
try (final Scanner user_input = new Scanner(System.in);
final PrintStream output = System.out;) {
final int no_of_employees = readInt(user_input, output, "Please enter number of users: ");
final Employee[] employees_list = new Employee[no_of_employees]; // either this line
final ArrayList<Employee> employees = new ArrayList<>(); // or this line
for (int i = 0; i < no_of_employees; i++) {
output.println("Creating user #" + (i + 1) + "...");
final Employee newEmployeeWithAddress = new Employee(user_input, output);
employees_list[i] = newEmployeeWithAddress; // either this line
employees.add(newEmployeeWithAddress); // or this line
}
}
}
}
I am trying to return some values of some objects by using getter and setter method. Now I can't return more than one value inside a single method. In this case, do I need to create different methods for each return. If not, how could I solve it?
My code:
package books;
public class BooksObject {
//variable for book 1
String name1 = "The brief history of time";
String isbn1 = "111";
String[] authName1 = {"S. Hawking", " Hawking's friend"};
//variable for book 2
String name2 = "100 years of solitude";
String isbn2 = "222";
String[] authName2 = {"G. Marquez", "Marquezs friend"};
//All setters
public void setBook1(String n_1, String i_1, String[] a_N1) {
name1 = n_1;
isbn1 = i_1;
String[] authName1 = a_N1;
}
public void setBook2(String n_2, String i_2, String[] a_N2) {
name2 = n_2;
isbn2 = i_2;
String[] authName2 = a_N2;
}
//All getters method
public String getBook1() {
return name1;
//return isbn1; //shows error
//return String[]authName1;//Shows error
}
}
[Note: Of course I am going to call all these method in my main class. I just haven't posted it here.]
You should create a Book class that contains the 3 properties, and your getter would return a Book instance.
Instead of
String name1 = "The brief history of time";
String isbn1 = "111";
String[] authName1 = {"S. Hawking", " Hawking's friend"};
You'll have
Book book1 = new Book ("The brief history of time", "111", {"S. Hawking", " Hawking's friend"});
Then :
public Book getBook1() {
return book1;
}
You can further improve your BooksObject by having a books array (Book[]) instead of a different variable for each Book. Then you wouldn't need a separate getBooki method for each book.
I think you shoul change your code as shown below:
public class Book
{
private String name;
private String isbn;
private String[] authors;
/* constructor */
public Book(String name, String isbn, String[] authors) {
this.name = name;
this.isbn = isbn;
this.authors = authors;
}
/* setter */
public void setName(String name) {
this.name = name;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public void setAuthors(String[] authors) {
this.authors = authors;
}
/* getter */
public String getName() {
return name;
}
public String getIsbn() {
return isbn;
}
public String[] getAuthors() {
return authors;
}
}
public class Main
{
public static void main(String[] args) {
Book book1 = new Book(
"The brief history of time",
"111",
new String[]{"S. Hawking", " Hawking's friend"}
);
Book book2 = new Book(
"100 years of solitude",
"222",
new String[]{"G. Marquez", "Marquezs friend"}
);
}
}
I am trying to print title from my member class using array in my library class
public class Book gives me this error :
http://screencast.com/t/tqpJp2BF8sH
{
// instance variables - replace the example below with your own
private int x;
private Integer bookid;
private String author;
private String title;
private String ficornonfic;
/**
* Constructor for objects of class Book
*/
public Book(Integer bookID, String Author, String Title, String FictionORnonfiction )
{
bookid = bookID;
author = Author;
title = Title ;
ficornonfic = FictionORnonfiction;
x = 0;
}
public String PrintListOfBooks()
{
return title;
}
public String toString() {
return "Title:" + title + " BookId: " + bookid + " Author: " + author + ".";
}
public int getTitle() {
return this.title;
}
}
---------------------------------------------------------
this is my library class
import java.util.ArrayList;
public class Library
{
private ArrayList<Member>listOfMembers;
public Library()
{
listOfMembers = new ArrayList<Member>();
listOfBooks = new ArrayList<Book>();
}
public void storeMember(Member Member)
{
listOfMembers.add(Member);
}
public int numberOfMembers()
{
return listOfMembers.size();
}
public void listMembers()
{
for (int item=0; item<listOfMembers.size(); item++ ) {
Member m = listOfMembers.get (item);
System.out.println(m.GetWholeName());
}
}
public Member findMember(int id) {
for(Member member : listOfMembers) {
if (member.getId() == id) {
return member;
}
}
return null;
}
private ArrayList<Book>listOfBooks;
public void storeBook(Book Book)
{
listOfBooks.add(Book);
}
public int numberOfBooks()
{
return listOfBooks.size();
}
public void listBooks()
{
for (int item=0; item<listOfBooks.size(); item++ ) {
Book b = listOfBooks.get (item);
System.out.println(b.PrintListOfBooks());
}
}
public Book findBook(string title) {
for(Book book : listOfBooks) {
if (book.getId() == id) {
return book;
}
}
return null;
}
}
I am trying to print title from my member class using array in my library class
public class Book gives me this error :
http://screencast.com/t/tqpJp2BF8sH
The title is a String, not an int. You can change the method signature to match the field type:
public String getTitle() {
return this.title;
}
First, as others have noted your title is a String not an int. So change the return type of getTitle() (or remove it altogether). Because it appears like you've correctly overridden toString() in Book to get all the information, and you could iterate the contents of your List with a for-each loop. Something like,
for (Book b : listOfBooks) {
System.out.println(b);
}
which is equivalent to
for (int i = 0; i < listOfBooks.size(); i++) {
Book b = listOfBooks.get(i);
System.out.println(b.toString());
}
Finally in Java, by convention, method names start with a lower case letter.
You are essentially telling the program to return an Integer when the value you wish to return is a String.
If you change int to String, the error will go away.
public String getTitle() {
return this.title;
}
I'm trying to make a program that creates a library of different books, I have set a number of copies for each item in the library and every time I check out an Item I want it to deduct 1 copy from only the particular object I check out but instead it takes a copy away from all the objects. not sure how to fix the problem.
public abstract class Item{
private int identify;
private String title;
private int copies;
public Item(){
identify=0;
title="N/A";
copies=0;
}
public Item(int id, int copy, String t){
identify=id;
copies=copy;
title=t;
}
public void setIdentificationNumber(int id){
identify = id;
}
public void setTitle(String t){
title=t;
}
public void setNumberCopies(int num){
copies=num;
}
public int getIdentificationNumber(){
return identify;
}
public String getTitle(){
return title;
}
public int getNumberCopies(){
return copies;
}
public void checkOut(){
if(copies>0){
copies-=1;
System.out.println("You have checked out "+title+". Thank You");
}
else{
System.out.println("All copies of "+title+" are checked out!");
}
}
public void checkIn(){
copies+=1;
}
}
The problem may also be in my client method I have posted the code for that as well below.
import java.util.Arrays;
import java.util.Scanner;
public class Library{
static String title;
static String author;
static int id;
static int copies;
static String date;
static Book[] database = new Book[100];
static int count=0;
public static void main(String[] args){
int i;
Scanner s = new Scanner(System.in);
do{
addBook();
System.out.println("would you like to add another book?");
i=s.nextInt();
}while(i == 0);
database[0].viewDetails();
database[1].viewDetails();
checkingOut();
database[0].viewDetails();
database[1].viewDetails();
}
public static void addBook(){
Scanner s = new Scanner(System.in);
System.out.println("Enter the title of the book you want to add to the collection");
title=s.nextLine();
System.out.println("Enter the author of the book you want to add to the collection");
author=s.nextLine();
System.out.println("Enter the publishing date of the book you want to add to the collection");
date=s.nextLine();
System.out.println("Enter the ID number of the book you want to add to the collection");
id=s.nextInt();
System.out.println("Enter the the number of copies that will be added into the collection");
copies=s.nextInt();
Book Book1 = new Book(date, author, copies, id, title);
database[count] = Book1;
count++;
}
public static void checkingOut(){
boolean found=false;
int idSearch;
int i=0;
Scanner s = new Scanner(System.in);
System.out.println("Enter the ID number of the book you want to check out");
idSearch=s.nextInt();
while(i<database.length && found!=true){
if(database[i].getIdentificationNumber() == idSearch){
found = true;
}
i++;
}
if(found==true){
database[i].checkOut();
System.out.println("There are "+database[i].getNumberCopies()+" copies left");
}
else{System.out.println("There is no book with that ID number!");}
}
}
In my addBook method I create a new object called book1 every time I make a new book, so I think that it may be changing all of the book objects every time I add a book. I'm not really sure of a better way to write the method.
here is my method for book also
public class Book extends WrittenItem{
public Book(){
super();
}
public Book(String date, String a, int copy, int id, String t){
super(a, date, copy, id, t);
}
public void viewDetails(){
System.out.println("ID: "+getIdentificationNumber()+"\nTitle: "+getTitle()+"\nAuthor: "+getAuthor()+" Date written: "+getDate()+"\nCopies available: "+getNumberCopies());
}
}
Any help would be greatly appreciated.
I can't 100% tell from your code, but I'm assuming Book extends Item. In that case, try something like this for Book constructor
public class Book extends Item {
String author;
String date;
public Book(String date, String author, int copies, int id, String title) {
super(id, copies, title); // Item constructor matches this super() call
// public Item(int id, int copy, String t)
this.author = author;
this.date = date;
}
}
You want Book to have the same copies at Item. So when you checkOut(), the Item number equals you input from the Book constructor. If you don't put the super() in the constructor, your Item copies will remain 0 and you will always get System.out.println("All copies of "+title+" are checked out!"); because copies is never > 0.
If your book is something like this,
public class Book extends Item {
private String date;
private String author;
public Book() {
}
public Book(String date, String author, int copies, int id, String title) {
super(id, copies, title);
this.author = author;
this.date = date;
}
void viewDetails() {
System.out.println("date:" + date + " author:" + author + " copies:" + getNumberCopies() + " id:" + getIdentificationNumber() + " title:" + getTitle());
}
}
Then your code should work fine, as i've tested, if you also add a break in your checkingOut() method,
public static void checkingOut() {
boolean found = false;
int idSearch;
int i = 0;
Scanner s = new Scanner(System.in);
System.out.println("Enter the ID number of the book you want to check out");
idSearch = s.nextInt();
while (i < database.length && found != true) {
if (database[i].getIdentificationNumber() == idSearch) {
found = true;
break; //add this
}
i++;
}
if (found == true) {
database[i].checkOut();
System.out.println("There are " + database[i].getNumberCopies() + " copies left");
} else {
System.out.println("There is no book with that ID number!");
}
}