Creating Java Classes - java

I am currently working on an inventory program involving a one dimensional array, 2 classes (Store and Book), and several other things such as methods and a constructor.
The Store class which is the main class I guess you could say is supposed to include the main() method, and is supposed to read a list of purchases from a file, process each purchase with an appropriate message (ISBN number, amount, price, or problem (such as out of stock or do not have)), store an array of up to 15 books of type Book, a method to read in the inventory file, method to process a purchase, a method to print the inventory at closing along with the number of books sold and amount made at closing.
The Book class includes, book objects (each book object holds ISBN String, price double, and copies int), constructor, getters and setters, and a method to print the information.
Since the array is supposed to be created in the Store class, but be of type Book and made up of the book objects (I'm assuming?), I'm having trouble figuring out how to do this properly (assigning values to the isbn, price, copies variables, setting up the constructor correctly, etc).
Update
The main issue I'm having right now is being able to print the book object from my printInfo method. I am getting an error message at the print statement of that method stating "cannot find symbol. symbol: book". I can't really see if the program is actually working yet since that's kind of what I need to see at this point (the printed out book object) before I start adding in a few more methods to do other things that depend on this book object being correct.
Here is the code I have come up with so far:
The Store class:
import java.util.Scanner;
import java.io.*;
public class Store {
public static void main(String[] args) throws Exception {
Book[] books = readInventory();
for (Book : books) {
System.out.printf("ISBN: %s, Price: %f, Copies: %d%n",
book.getISBN(), book.getPrice(), book.getCopies());
}
}
public static Book[] readInventory() throws Exception {
Book[] books = new Book[15];
java.io.File file = new java.io.File("../instr/prog4.dat");
Scanner fin = new Scanner(file);
String isbn;
double price;
int copies;
while (fin.hasNext()) {
for(int i = 0; i < books.length; i++) {
isbn = fin.next();
price = fin.nextDouble();
copies = fin.nextInt();
Book book = new Book(isbn, price, copies);
books[i] = book;
}
}
fin.close();
return books;
}
public static void printInfo(Book[] books) {
System.out.println(book);
}
}
And here is my Books Class:
public class Book {
private String isbn;
private double price;
private int copies;
public Book(String isbnNum, double priceOfBook, int copiesInStock) {
isbn = isbnNum;
price = priceOfBook;
copies = copiesInStock;
}
public String getISBN() {
return isbn;
}
public double getPrice() {
return price;
}
public int getCopies() {
return copies;
}
public void setISBN(String isbn) {
this.isbn = isbn;
}
public void setPrice(double price) {
this.price = price;
}
public void setCopies(int copies) {
this.copies = copies;
}
#Override
public String toString() {
return String.format("ISBN: %s, Price: %f, Copies: %d%n",
this.getISBN(), this.getPrice(), this.getCopies());
}
}
This is my first time working with classes, or at least creating multiple classes in the same program, so I'm still trying to figure out how this works. I've been reading a tutorial I found online that has been somewhat helpful, but I'm having trouble applying it to this specific type of program.
Any suggestions would be greatly appreciated.

Hi glad to see you've made the effort to actually try something before jumping on here. What you have done is pretty good so far. But what you really need now is a getter and setter method in your class Book. These will allow you to return or set the value of the variable for the object.
public class Book {
private String isbn;
private double price;
private int copies;
public Book(String isbnNum, double priceOfBook, int copiesInStock) { // Constructor?
isbn = isbnNum;
price = priceOfBook;
copies = copiesInStock;
}
public String getISBN() {
return this.isbn;
}
public double getPrice() {
return this.price;
}
public int getCopies() {
return this.copies;
}
public void setISBN(String value) {
this.isbn = value;
}
public void setPrice(double value) {
this.price = value;
}
public void setCopies(int value) {
this.copies = value;
}
}
This should help you get on the right track. Depending on how you want the information to come up would depend on whether you add System.out.println("ISBN: " + this.isbn); and so on in each get function, or you could declare a separate function getInfo which simply prints each. Or if you were returning it into store you could always print it that way. One more thing to note is that you have been declaring books as Book[] books = new Book[15] as you are creating an array of Book objects and not strings. If you need any more help let me know.

1.you shouldn't use String Array.you should declare Book Array instead. then It will be easier to assign your Book object.
for example
Book[] books = new Book[15];
books[i] = new Book(isbnNum,priceOfBook,copiesInStock);
2.because variable in Book class was declare in private type. you should create get methods in your Book class to get variable in any object.
for example
public String getbnNum()
{
return isbn;
}
public double getprice(){
return price;
}
public int getcopies(){
return copies;
}

I wrote comments in the code for you. I have to assume your file-reading code is correct since I don't have the file.
import java.util.Scanner;
public class Store {
/*
* This is the main method. It is where the code that starts off the
* application should go.
*/
public static void main(String[] args) throws Exception {
// Here, we take the array returned by the method and set it to a local variable.
Book[] books = readInventory();
// This is an alternative notation than a normal for-loop.
for (Book book : books) {
System.out.printf("ISBN: %s, Price: %f, Copies: %d%n",
book.getISBN(), book.getPrice(), book.getCopies());
}
/* Alternative to above.
for (int i = 0; i < books.length; i++) {
Book book = books[i];
System.out.printf("ISBN: %s, Price: %f, Copies: %d%n",
book.getISBN(), book.getPrice(), book.getCopies());
}
*/
}
// We add the return type of Book[] so we can get a reference to our array.
public static Book[] readInventory() throws Exception {
Book[] books = new Book[15];
java.io.File file = new java.io.File("../instr/prog4.dat");
Scanner fin = new Scanner(file);
// These variables don't need to be initialized yet.
String isbn;
double price;
int copies;
while (fin.hasNext()) {
// Fill the books array with Book objects it creates from the file.
for (int i = 0; i < books.length; i++) {
isbn = fin.next();
price = fin.nextDouble();
copies = fin.nextInt();
Book book = new Book(isbn, price, copies);
books[i] = book;
}
}
fin.close();
return books;
}
}
Book class:
public class Book {
private String isbn;
/*
* Careful using double as your type for variables that hold money values.
* If you do any division, you can end up getting answers different than
* what you might expect due to the way Java handles remainders. For that,
* make price a Currency type, which you can import from Java.util
*/
private double price;
private int copies;
public Book(String isbnNum, double priceOfBook, int copiesInStock) {
isbn = isbnNum;
price = priceOfBook;
copies = copiesInStock;
}
// This is an example of a getter method, which we need since our isbn is
// declared as private. Now, other methods can still read what isbn is.
public String getISBN() {
return isbn;
}
public double getPrice() {
return price;
}
public int getCopies() {
return copies;
}
/*
* We can use the "this" keyword to refer to this instance's isbn variable,
* instead of the local variable isbn that was passed to the method.
* Therefore, in this tricky notation we are setting the object's isbn
* variable to the isbn variable passed to the method.
*/
public void setISBN(String isbn) {
this.isbn = isbn;
}
public void setPrice(Double price) {
this.price = price;
}
public void setCopies(int copies) {
this.copies = copies;
}
}
Also note that a more advanced way to print the information for each book would be to make a toString() method in the Book class which overrides the default toString method it inherits from the generic Object class. You should use a special convention called an override annotation to do this as it is considered good practice when we redefine methods from a superclass (Object is a superclass of all objects, including Book).
#Override
public String toString() {
return String.format("ISBN: %s, Price: %f, Copies: %d%n",
this.getISBN(), this.getPrice(), this.getCopies());
}
That would allow us to simply call System.out.println(book);, for example, and would also mean we wouldn't have to rewrite all of this code every place we want to print a book. This is an important principle with objects—they generally should take care of themselves.

Related

JAVA : reading lines from a txt file and create an object

I'm a new student in computer science and i have to create an inventory program that read informations about products from a txt file in this format: Department;unit of measure;quantity;price;unique code;name; (example: E;U;20;1,50;87678350;Lamp) .Subsequently i have to :
-calculate the total value of the stock
-selling of a product
-insertion of a product
-searching of a product by unique code.
If there are lines with the same unique code, the program will report an error.
I managed to read the lines in the txt file but i dont have any idea on how to calculate the total value of the stock from it.
public class Emporium{
public static void main (String[]args) throws IOException {
Scanner input = new Scanner(new File("EMPORIUM.txt"));
input.useDelimiter(";|\n");
Product[] products = new Product[0];
while(input.hasNext()) {
String department = input.next();
String unit=input.next();
int quantity=input.nextInt();
double price=input.nextDouble();
long code=input.nextLong();
String name=input.next();
Product newProduct = new Product(department,unit,quantity,price,code,name);
products= addProducts(products,newProducts);
}
for (Product product: products) {
System.out.println(product);
}}private static Product[] addProduct(Product[] products, Product productToAdd) {
Product[] newProducts =new Product[products.length+1];
System.arraycopy(products,0,newProducts,0, products.length);
newProducts[newProducts.length-1]= productToAdd;
return newProducts;
}
public static class Product {
protected String department;
protected String unit;
protected int quantity;
protected double price;
protected long code;
protected String name;
private static NumberFormat formatter = new DecimalFormat("#0.00");
public Product(String dep,String uom,int qnt,double prz,long cod,String nm) {
department=dep;
unit=uom;
quantity=qnt;
price=prz;
code=cod;
name=nm;
}
#Override
public String toString() {
return String.format(department+";"+unity+";"+quantity+";"+formatter.format(price)+";"+code+";"+name);
}
}
}
My question is: How can i read the value of the product in the file and sum it with the prices of the other products ? This mean that i need to do the same with the unique code to find a specific product.
Thank you very much in advance for your assistance.
The correct method would be to have Getters and Setters in your Product Class.
As you can see in your code, you just pass in your variables and initiate them in your constructor, but initializing them using getters and setters is better as it is a good programming practice and adds more functionality to your code.
Example
public static class Product {
protected String department;
protected String unit;
protected int quantity;
protected double price;
protected long code;
protected String name;
private static NumberFormat formatter = new DecimalFormat("#0.00");
public Product(String dep,String uom,int qnt,double prz,long cod,String nm) {
setDep(dep);
setUom(uom);
setQnt(qnt);
setPrz(prz);
setCod(cod);
setNm(nm);
}
public void setPrz(double prz){
this.price = price;
}
//Other setters
public double getPrz(){
return price;
}
//Other getters
#Override
public String toString() {
return String.format(department+";"+unity+";"+quantity+";"+formatter.format(price)+";"+code+";"+name);
}
}
With getters and setters in your Products Class, you can:
Create a method that calculates the sum of all Products in your ArrayList
Search for a particular product in your array using your unique identifier
Sort your Arraylist by a variable, be it department, price etc.
You've already read your products into an array, you need to loop through the array and add together price * quantity for each one.
For example...
double totalValue = Arrays.stream(products).mapToDouble(p -> p.quantity * p.price).sum();
This will iterate over each product and map each product to a double (which is the quantity times the price for that product) it then sums all of those results.

How to print a object with constructor from another class (constructor) (java)

I have two classes ("Startup.java" and "Book.java").
My goal is to print all object(s) from "Book.java".
To call the view() method, I initialized a new 'book-object'. The problem is:
if I call "book.view", it print's '0nullnull0' (I know, it's because of the constructor), I have no idea how to fix it. Here you can see the code:
package array;
import java.util.*;
public class Startup{
public static void main(String[] args) {
Book book = new Book(0, null, null, 0);
book.view();
}
package array;
public class Book {
private int number;
private String title;
private String language;
private int price;
public Book(int number, String title, String language, int price) {
this.number = number;
this.title = title;
this.language = language;
this.price = price;
}
public void add() {
Book b1 = new Book(1, "title", "de", 2);
}
public void view() {
System.out.println(number + title + language + price);
}
}
You have initialized your object using
Book book = new Book(0, null, null, 0);
Hence, the output is coming like that.
I think you want the values in your add method (not sure what that method is for?) to be printed.
So, you need to call your constructor with those values.
Book book = new Book(1, "title", "de", 2);
book.view();
You can print all Book objects by storing the objects in an array and then iterating through the array and call the list function for each Object of the array
Book[] bookArray=new book[n];
Add your objects to this array
Now iterating through the array you would be able to print all the objects
for(int i=0;i<n;i++) {
bookArray[i].view();
}

Making a copy of a BookOrder within BookOrder

I'm trying to make a copy of a BookOrder that I've already created, however, it isn't creating properly. So far, I have this.
public class BookOrder
{
private String author;
private String title;
private int quantity;
private double costPerBook;
private String orderDate;
private double weight;
private char type; //R,O,F,U,N
public BookOrder (String author, String title)
{
}
public BookOrder(String author, String title, int quantity, double costPerBook, String orderDate, double weight, char type)
{
this.author= author;
this.title= title;
this.quantity= quantity;
this.costPerBook= costPerBook;
this.orderDate= orderDate;
this.weight= weight;
this.type=type;
}
public BookOrder(BookOrder bookOrder)
{
}
However, when I try to copy this here:
public class TestBookOrder
{
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
Utility.myInfo("11/5,2013", "Project4");
Utility.pressEnterToContinue();
Utility.clearScreen();
BookOrder BookOrder1 = new BookOrder("Jonathan", "Book1", 12, 6.75, "11/5/2013", 8.75, 'r');
System.out.print(""+ BookOrder1.invoice());
BookOrder copyA = new BookOrder(BookOrder1);
BookOrder copyB= new BookOrder(BookOrder1);
copyB.adjustQuantity(-5);
System.out.print("\n"+ copyB.invoice());
System.out.print("\n"+ copyA.invoice());
}
}
it just returns the invoice for copyA and copyB as null and 0. Anyone know what code needs to be within the copy method?
To make this work, you need to change following code. This will create a new Object and will populate same with BookOrder value passed as input. Hope this answers your doubt.
public BookOrder(BookOrder bookOrder)
{
this.author= bookOrder.getAuthor();
this.title= bookOrder.getTitle();
this.quantity= bookOrder.getQuantity();
this.costPerBook= bookOrder.getCostPerBook();
this.orderDate= bookOrder.getOrderDate();
this.weight= bookOrder.getWeight();
this.type=bookOrder.getType();
}
You need to copy the values of the parameter BookOrder into your current parameters.
e.g.,
class Foo {
private int bar;
public Foo(Foo foo) {
this.bar = foo.bar;
// same for other fields if they exist.
}
}
Incidentally, you will want to fix this:
public BookOrder (String author, String title)
{
}
You're throwing out the parameters passed into this constructor, completely ignoring them.
Edit: this was already explained to you in a previous answer to a previous question on the same assignment!
That's because you need to assign all the fields from the passed object to the current object, in the copy constructor.
public BookOrder(BookOrder bookOrder) {
this.author = bookOrder.getAuthor(); // since they are private and thus you need getter to get the values
this.title = bookOrder.getTitle();
this.quantity = bookOrder.getQuantity();
this.costPerBook = bookOrder.getCostPerBook();
this.orderDate = bookOrder.getOrderDate();
this.weight = bookOrder.getWeight();
this.type =bookOrder.getType();
}

Java arraylist incompatible types error

The answer to this will probably turn out to be obvious in retrospect but for now I find myself rather stuck on this. I'll give some blocks of code first and then present the problem.
This is part of my class Stockmanager, I have omitted some methods that have nothing to do with this problem.
import java.util.ArrayList;
public class StockManager
{
private ArrayList stock;
public StockManager()
{
stock = new ArrayList();
}
public void addProduct(Product item)
{
stock.add(item);
}
public Product findProduct(int id)
{
int index = 0;
while (index < stock.size())
{
Product test = stock.get(index);
if (test.getID() == id)
{
return stock.get(index);
}
index++;
}
return null;
}
public void printProductDetails()
{
int index = 0;
while (index < stock.size())
{
System.out.println(stock.get(index).toString());
index++;
}
}
}
Here's my class Product, again with some methods omitted.
public class Product
{
private int id;
private String name;
private int quantity;
public Product(int id, String name)
{
this.id = id;
this.name = name;
quantity = 0;
}
public int getID()
{
return id;
}
public String getName()
{
return name;
}
public int getQuantity()
{
return quantity;
}
public String toString()
{
return id + ": " +
name +
" voorraad: " + quantity;
}
}
My problem lies in the fact that I get a compile time error in the findProduct() method. To be more specific the line Product test = stock.get(index); is indicated with a message incompatible types.
The constructor of StockManager creates a new ArrayList with the name stock. As is evident from the method addProduct() this ArrayList contains items of the type Product. The Product class has a number of variables one of which is called id and is of type integer. That class also contains a method getID() that returns an id.
As far as I know, the way of getting an item from an arraylist is the get() method with the number between the () indicating the item's position. Seeing as my arraylist contains instances of Product, I expect to get a Product as result when I use the get() method on the arraylist. So I don't understand why it doesn't work when I define a variable called test of the type Product and try to assign an item from the arraylist to it. I have as far as I know, successfully used this same technique in the method printProductDetails() where I use the toString() method from Product on the object from the arraylist.
I hope someone will be able to clarify for me where I am at fault. If it makes any difference, I am doing this stuff in BlueJ which is probably not the best tool for it but it is the one I'm supposed to use for this school project.
private ArrayList stock;
You should redeclare this with a bounded type like so:
private List<Product> stock = new ArrayList<Product>();
If you don't, this line:
Product test = stock.get(index);
won't work because you're trying to assign a raw Object to a Product.
Others have suggested casting the Object to a Product, but I wouldn't recommend this.
Your stock is defined as private ArrayList stock, which means that stock.get() returns an Object without any special type. You should either make Stock an ArrayList of Products
ArrayList<Product> stock;
or cast the result of the get method manually
Product test = (Product)stock.get(whatever);
Product test = (Product) stock.get(index);
or if you make your list List<Product> stock your line should work without changes.

Error: the method getId() is undefined for the type List<Product>

I have a method to create a list of objects of class
public List<Product> initProducts(){
List<Product> product = new ArrayList<Product>();
Product prod = new Product(product.getId(),product.getItemName(),product.getPrice(),product.getCount());
product.add(prod);
return product;
}
My Product class is:
public class Product {
int ItemCode;
String ItemName;
double UnitPrice;
int Count;
/**
* Initialise the fields of the item.
* #param Name The name of this member of product.
* #param id The number of this member of product.
* #param Price The price of this member of product.
*/
public Product(int id, String Name, double Price, int c)
{
ItemCode=id;
ItemName=Name;
UnitPrice=Price;
Count = c;
}
public int getId()
{
return this.ItemCode;
}
public String getItemName()
{
return this.ItemName;
}
public double getPrice()
{
return this.UnitPrice;
}
public int getCount()
{
return this.Count;
}
/**
* Print details about this members of product class to the text terminal.
*/
public void print()
{
System.out.println("ID: " + ItemCode);
System.out.println("Name: " + ItemName);
System.out.println("Staff Number: " +UnitPrice);
System.out.println("Office: " + Count);
}
}
I am getting an error that the method getId() is undefined for the type List<Product>, Similarly for other methods. Please help me out with this error.
Is my statement correct??
Product prod = new Product(product.getId(),product.getItemName(), product.getPrice(),
product.getCount());
product.add(prod);
product is a reference of List
List<Product> product = new ArrayList<Product>();
which doesn't have that method
product is reference to List object.
and List/ArrayList has no methosd named getId().
You have written getId() method for Prodct class , so you can call this method using ref to Product class object.
If you want to get any product object form list use get(int index) method of ArrayList.
eg.
Product prod = product.get(0);
String id= prod.getId();
I believe, the reason you are facing this issue is more due not following the code conventions, that any other.
Whenever you make a collection of any objects, the convention is to use plurals for reference names of the collection. And singular reference name of the Object itself.
You can find more details here.
Below is the re-written code with the code conventions being followed:
Method to create a list of objects of class Product:
public List<Product> initProducts(){
List<Product> products = new ArrayList<Product>();
Product product = new Product(products.getId(), products.getItemName(), products.getPrice(), products.getCount());
products.add(prod);
}
Product Class:
class Product {
int itemCode;
String itemName;
double unitPrice;
int count;
public Product(int itemCode, String itemName, double unitPrice, int count)
{
this.itemCode = itemCode;
this.itemName = itemName;
this.unitPrice = unitPrice;
this.count = count;
}
public int getId()
{
return this.itemCode;
}
public String getItemName()
{
return this.itemName;
}
public double getPrice()
{
return this.unitPrice;
}
public int getCount()
{
return this.count;
}
}
Now, it is easy to see, that the products Object (which is of the type List) will not have any methods name getId() or getCount(). Infact , these are methods of the Object contained in the List.
Following conventions will help you avoid, such hassles in futures.
Is my statement correct??
Product prod = new Product(product.getId(),product.getItemName(), product.getPrice(),
product.getCount());
product.add(prod);
NO this is incorrect. product is not an instance of class Product,rather it is an instance of List. List does not have any method called getId.
If you want to retrieve the elements from the list and use it to create another instance of you can do something like:
Product exisProd = product.get(0);
Product prod = new Product(exisProd .getId(),exisProd .getItemName(), exisProd .getPrice(),
exisProd .getCount());
But make sure that you have elements in the list, otherwise u may run into exception.
product.add(prod);

Categories