is this the correct use of aggregation - java

I want to simulate a cash register system. At the end of the transaction, the receipt would be displayed on the monitor. I've created a class called Receipt, it contains info about items purchased by the customer, subtotal, and customer's name. So, in the Receipt class, I created an ArrayList of product and a buyer object as instance variables. The toString() function would return a nice formatted string.
I am not sure if I should use ArrayList as an instance variable and I don't know if aggregation is the best choice here.
import java.util.ArrayList;
public class Receipt {
private ArrayList<Product> purchased_products;
private double total_price;
private double total_with_tax;
private Buyer buyer;
public Receipt(Buyer buyer, ArrayList<Product> purchased_products,
double total_price, double total_with_tax) {
this.purchased_products = new ArrayList<>(purchased_products);
this.total_price = total_price;
this.buyer = buyer;
this.total_with_tax = total_with_tax;
}
#Override
public String toString() {
String content = "Receipt: \nConvenience Store\n";
content += "Balance Summary:\n";
for (Product product : purchased_products) {
content += product + "\n";
}
content += String.format("%d Subtotals: $%.2f\nAmount Paid: $%.2f\n", purchased_products.size(), total_price,
total_with_tax);
content += buyer.toString() + "\n";
content += "Thank you for shopping with us. Have a wonderful day!\n";
return content;
}
}

Everything looks fine and you are doing it correct almost.
A small correction in constrctor is you need not to have a new array list again.
Just
this.purchased_products = purchased_products;
Is enough.

Related

Two instance variables in the class of a one dimensional array

I'm hoping someone can help me out with a question that I've been stuck on for quite a while.
Just to clarify the scenario. There is a show being held in a theatre that can hold 180 people. They allow online bookings that are written to a text file "bookings.txt" Individual bookings are single that only have a seat, contact and payment status record. Whereas group bookings have seats, a contact number, payment status, group name and group size records.
So far I have created the Bookings and GroupBookings classes. I'll show them below:
/**
*
* #author OP
*/
public class Booking
{
public String seat;
public String contact;
public double cost;
public boolean paid;
//Constructor
public Booking(String st, String ct, int cost, boolean pd)
{
seat = st;
contact = ct;
this.cost = cost;
paid = pd;
}//end of Booking
//Getters
public String getSeat()
{
return seat;
}//end of getSeat
public String getContact()
{
return contact;
}//end of getContact
public boolean isPaid()
{
return paid;
}//end of isPaid
public double getCost()
{
//Determining what discount should be applied to their seat location
if (seat.contains("A") || seat.contains("B") ||
seat.contains("C") || seat.contains("D"))
{
cost = 200;
}
else
{
if (seat.contains("E") || seat.contains("F") ||
seat.contains("G") || seat.contains("H"))
{
cost = 160;
}
else
{
if (seat.contains("I") || seat.contains("J") ||
seat.contains("K") || seat.contains("L"))
{
cost = 120;
}
}
}//end of nested if statement
return cost;
}//end of getCost
#Override
public String toString()
{
return seat + "\t" + "R" + cost + "\t" + paid;
}//end of toString
}//end of class booking
/**
*
* #author OP
*/
public class GroupBooking extends Booking
{
private String groupName;
private int groupSize;
public GroupBooking(String st, String ct, boolean pd, String gn, int gs)
{
//Variables from previous class (using inheritance)
super.seat = st;
super.contact = ct;
super.paid = pd;
//New variables for this class
groupName = gn;
groupSize = gs;
}//end of GroupBooking
#Override
public double getCost()
{
cost = super.getCost();
for (int i = 0; groupSize % 4 > i; i++)
{
cost = cost - 60;
i++;
}//end of for loop
return cost;
}//end of getCost
public int getGroupSize()
{
return groupSize;
}//end of getGroupSize
public String getGroupName()
{
return groupName;
}//end of getGroupName
#Override
public String toString()
{
return seat + "\t" + "R" + cost + "\t" + groupName;
}//end of toString
}//end of class GroupBooking
Now for the question that I am stuck on:
A new class has to be created called BookingManager. From there I have to declare two instance variables in the class of one-dimensional array that can be used to store up to 180 Booking or GroupBooking objects. An integer counter must also be created to keep track of how many Bookings are stored in the array. (These two instance variables should not be accessible from outside the class)
I'm still a newbie in coding and I'm unsure of what to do here. The follow-up question is also giving me difficulties:
A contractor then has to be created to read the information from the text file "bookings.txt". Each line either contains a single Booking or a GroupBooking object. Read each line from the file and instantiate the appropriate type of object (Booking or GroupBooking) and add it to the array. (Note in the case of GroupBooking you must create an object in the array for each member of the group. Exp for a group of six you have to have six separate GroupBooking objects in the array.)
I know a file scanner is needed from the second question but I have no idea whether to use a for loop or an if statement to differentiate between a single booking or a group booking.
If anyone can help I would truly appreciate it. This topic is still very new to me.
To prevent a variable being accessible outside a class declare the variable "private". e.g.
private String costtotal="";
An instance variable "is not" static ("is not" a class member variable), and are a global variable only declared at the top of the class code below the import statements, so exist until the class exits.
In your manager class you need a global variable array Booking class
Booking[] bookings;
private String costtotal=""; // e.g.
// in the constructor read the bookings file and find the number of bookings made
//int totalbooked=...whatever reading the file data counts to of bookings made;
bookings=new Booking[totalbooked];
// create and fill each Booking object and assign it to its index on the array in a loop
bookings[loopcount]=new Booking(st,ct,cost,pd);
Different schemes of class systematics of coding
// bean syntax in a java bean framework class type
public void setCosttotal(String costtotal){
this.costtotal=costtotal;
}
//bean syntax
public String getCosttotal(){
return costtotal;
}
// normal non bean syntax 1
public String costTotal(String csttot){
return (String)csttot;
}
// somewhere else in code in scope to global variable
costtotal=costTotal(valuein);
// normal non bean syntax 2
public String costTotal(String csttot){
costtotal=csttot;
return costtotal;
}

Listing Parameters of an Object in an ArrayList

I am trying to create a method to list the elements in an ArrayList, but the method only returns the values of the most recent object:
The object:
//Constructor for guests at the hotel
public Guest (String name, String checkinDate, String checkoutDate, double depAmt)
{
gstName = name;
checkIn = checkinDate;
checkOut = checkoutDate;
deposit = depAmt;
}
Current objects in the ArrayList:
//Fills the roster with three guests to start the program
public static void fillGuest()
{
Guest guest1 = new Guest("Mike P.", "2/13/16", "2/23/16", 360.00);
guestList.add(guest1);
Guest guest2 = new Guest("Randall M.", "4/10/16", "4/17/16", 120.00);
guestList.add(guest2);
Guest guest3 = new Guest("Bo-Diddly.", "4/20/16", "4/23/16", 600.00);
guestList.add(guest3);
}
Method to list the objects in the ArrayList:
public static void returnGuests()
{
System.out.println("Currently checked in " + guestList.size() + " guests:");
for (int i = 0; i <= guestList.size() - 1; i++)
{
System.out.println(guestList.get(i));
}
}
The output:
Currently checked in 3 guests:
Bo-Diddly. 4/20/16 4/23/16 600.0
Bo-Diddly. 4/20/16 4/23/16 600.0
Bo-Diddly. 4/20/16 4/23/16 600.0
Enter command:
How do I display the individual object parameters of each Guest object?
Your Guest object should look like below. Note the lack of the static modifier on the fields. Also, note the use of the this keyword. If you use that with a static variable, then your IDE should give you a warning that it will be interpreted as a MyClass.var instead of this.var.
Your problem is that all Guest objects will have the last set of variables as you create new Guest objects. You need to use "instance" variables instead of "class" variables.
If you would like to read more on the topic of static "class" variables, please see Understanding Class Members.
public class Guest {
String gstName, checkIn, checkOut;
double deposit;
public Guest (String name, String checkinDate, String checkoutDate, double depAmt)
{
this.gstName = name;
this.checkIn = checkinDate;
this.checkOut = checkoutDate;
this.deposit = depAmt;
}
}

Java target/select class/object - confused (sorry for bad title)

What I have below is producing the desired results by print some employee details along with weekly / monthly wages as appropriate.
However I understand that I should not be inputting data in the constructor as I've done.
I need to prompt for a hours worked value only for "PartTimeEmployees", just not the way I've done it.
I've tested with For-Each loops, Enhanced For loops and using the instanceOf operator.
If I could get some guidance/hints or examples of how to accomplish what is currently being done in the constructor, but in the TestEmployee class instead that would be great.
Mostly I'm not sure how to even describe what I'm trying to achieve. This hinders Googling somewhat. (Help with a better title would also be great)
Thanks in advance.
public class TestEmployee
{
public static void main(String[] args)
{
int size;
Employee[] employees = new Employee[4];
employees[0] = new FullTimeEmployee("Jane", 26000);
employees[1] = new PartTimeEmployee("Jack");
employees[2] = new FullTimeEmployee("Lucy", 52000);
employees[3] = new PartTimeEmployee("Lenny");
for(int i = 0; i < employees.length; i++)
{
employees[i].print();
}
}
}
Class: PartTimeEmployee - Constructor:
public PartTimeEmployee(String thisName)
{
super(thisName);
System.out.println("Please enter the number of hours worked by " + thisName + ": ");
numHours = keyboard.nextInt();
setHours(numHours);
}
If I get your question, below might fit with your need -
First of all create generic Employee class -
class Employee {
private String name;
private int workingHours;
private final boolean IS_PART_TIME_EMP;
public Employee(String name, int workingHours) {
this.name = name;
this.workingHours = workingHours;
this.IS_PART_TIME_EMP = false;
}
public Employee(String name) {
this.name = name;
this.IS_PART_TIME_EMP = true;
}
public String getName() {
return name;
}
public int getWorkingHours() {
return workingHours;
}
public void setWorkingHours(int workingHours) {
this.workingHours = workingHours;
}
public boolean isPartTimeEmployee() {
return IS_PART_TIME_EMP;
}
}
Now you can use it as per your requirement.
Employee[] employees = new Employee[4];
employees[0] = new Employee("Jane", 26000);
employees[1] = new Employee("Jack");
employees[2] = new Employee("Lucy", 52000);
employees[3] = new Employee("Lenny");
Scanner sc = new Scanner(System.in);
for (Employee employee : employees) {
if(employee.isPartTimeEmployee()) {
System.out.println("Please enter working hours by " + employee.getName() + ": ");
int numHours = sc.nextInt();
employee.setWorkingHours(numHours);
}
}
Constructor is not meant for user input.Its main intention is to initialize object of that class.
Instead of doing that in constructor,you can try something like this
employees[1] = new PartTimeEmployee("Jack");
System.out.println("Please enter the number of hours worked by " + employees[1].getName()+ ": ");
numHours = keyboard.nextInt();
employees[1].setHours(numHours);
You most likely will have some logical main loop in your program, like
while(!quit) {
// 1. ask if you want to add part time or full time employee
// 2. ask proper questions
// 3. call correct constructor
}
Writing such small pseudo code algorithm should be self explanatory and get you going.
Step one: presentation of options available for user and reading user input.
Step two: performing actions depending on user input from step 1
Step three: final call to proper constructor depending on results from steps 1 and 2
If I understood your question correctly (which I'm really not sure of) you want to prompt for the employee data in the main method.
In that case I'd use a loop and query the following things:
name of the employee
does the employee work full time? (y/n)
if yes: what is the wage? (assume hours = whatever a full time employee works a day)
if no: how many hours? (and probably the hourly wage as well)
Then use that information to construct an Employee object (I don't see any need for the subclasses here).

get specific value from arraylist element

Sorry if this is an easy answer or has been answered, but have searched and couldnt find anything. I am currently creating a supermarket checkout line with the products in a DefaultListModel, each product having a name, price, weight and code as shown below
public class Product {
private String name;
private double weight;
private double price;
private int code;
public Product (){
}
public Product (String Name, double kg, double pounds, int id){
name = Name;
weight = kg;
price = pounds;
code = id;
public String toString (){
return name + " - " + "£" + price + " Product # " + code;
and the products put into a list
public class productList extends DefaultListModel {
public productList (){
super();
}
public void addProduct (String name, double weight, double price, int code){
super.addElement(new Product(name, weight, price, code));
this has been used in the GUI for the checkout in the code segments as follows
private DefaultListModel defaultMainList = new DefaultListModel();
//other code
currentBasket.setModel(defaultMainList); //currentBasket is name of jlist
productsList = new productList();
productsList.addProduct("bananas", 0.5, 0.99, 1);
productsList.addProduct("apples", 0.8, 1.39, 2);
//etc etc, other products emitted
mainCheckoutList.setModel(productsList);
//unimportant code
addBasketItem = new JButton();
getContentPane().add(addBasketItem);
addBasketItem.setText("Add >");
addBasketItem.setBounds(215, 108, 62, 31);
addBasketItem.addActionListener(new ActionListener(){
public void actionPerformed (ActionEvent e){
defaultMainList.addElement(productsList.getElementAt(mainCheckoutList.getSelectedIndex()));
mainTillPrice.setText((defaultMainList.toString()));
this current code adds the item from the jlist on the left (main checkout list, which is my list of available products) to the jlist on the right which is my basket. It also adds the entire string of characters in the right list to the jtextfield called mainTillPrice, i want to know if there is any way just to add the price, eg. for the bananas object add 0.99, and then with subsequent items added add their prices as well to keep a running total. Any help would be appreciated and again sorry for any problems in explanation or code, i am fairly new.
Well, I wouldn't be using defaultMainList.toString(). You will need to get the Product which is been added, get the price of the Product and add it to the current tally. This value would then need to be added to the mainTillPrice text field
public void actionPerformed (ActionEvent e){
Product product = (Product)mainCheckoutList.getSelectedItem();
defaultMainList.addElement(product);
runningTally += product.getPrice();
mainTillPrice.setText(NumberFormat.getCurrencyInstance().format(runningTally));
This will require you to create an instance field called runningTally and assumes you have a method getPrice in your Product

Incrementing value in a Map (JAVA)

I'm having a problem with this home work assignment. I can handle the syntax, but not the logic. Could you provide me some tips.
What I'm trying to achieve is that the add method would increase the amount of products by using the increaseAmount method. Now it resets the value of amount to "1" every time I call the method. What makes this complicated is that I'm not allowed to use any other private variables than already used.
private Map<String, Purchase> shoppingCart = new HashMap<String, Purchase>();
public void add (String product, int price) {
Purchase purchase = new Purchase (product, 1, price);
//the line abowe returns the value back to 1 which I don't want.
if(shoppingCart.containsKey(product)) {
shoppingCart.put(product, purchase);
purchase.increaseAmount();
}
else {
shoppingCart.put(product, purchase);
The product constructor:
public Ostos(String product, int amount, int price) {
Code for the increaseAmount method:
private int amount;
public void increaseAmount() {
this.amount = (this.amount + 1);
Don't create a new purchase at the beginning only create it if it's not already there
public void add (String product, int price) {
if(shoppingCart.containsKey(product)) {
Purchase purchase = shoppingCart.get(product);
purchase.increaseAmount();
//You might have to put the purchase back into the cart I'm not sure
}
else {
Purchase purchase = new Purchase (product, 1, price);
shoppingCart.put(product, purchase);
}
You have to retrieve the value from shoppingCart and then increment the amount. You're never calling shoppingCart.get, so you're replacing the value each time by blindly putting the new purchase object into the map.

Categories

Resources