I'm trying to read a data file like this:
N 1000.0 NY
R 2000.0 CA 0.09
R 500.0 GA 0.07
N 2000.0 WY
O 3000.0 Japan 0.11 20.0
N 555.50 CA
O 3300.0 Ecuador 0.03 30.0
R 600.0 NC 0.06
and use it to fill an arrayList
My program consists of a abstract class and three classes to implement it:
1. NonProfitOrder
public class NonProfitOrder extends Order {
public NonProfitOrder(double price, String location) {
super(price, location);
}
public double calculateBill() {
return getPrice();
}
public String printOrder(String format){
String Long = "Non-Profit Order" + "\nLocation: " + getLocation() + "\nTotal Price: " + getPrice();
String Short = "Non-Profit Order-Location: " + getLocation() + ", " + "Total Price: " + getPrice();
if (format.equals("Long")){
return Long;
}
else{
return Short;
}
}
}
2. RegularOrder
public class RegularOrder extends Order {
double taxRate;
public RegularOrder(double price, String location, double taxRate) {
super(price, location);
this.taxRate = taxRate;
}
private double calcTax() {
double tax;
tax = getPrice() * taxRate;
return tax;
}
public double calculateBill() {
double bill;
bill = price + calcTax();
return bill;
}
public String printOrder(String format){
String Long = "Regular Order" + "\nLocation: " + getLocation() + "\nPrice: " + getPrice() +
"\nTax: " + calcTax() + "\nTotal Price: " + calculateBill();
String Short = "Regular Order-Location: " + getLocation() + ", " + "Total Price: " + calculateBill();
if (format.equals("Long")){
return Long;
}
else{
return Short;
}
}
}
and another very similar to RegularOrder
My problem comes in my main. I have to use a method readOrders(fileName:string):ArrayList<Order>
public static ArrayList<Order> readOrders (String fileName) throws FileNotFoundException{
String type;
Scanner s = new Scanner(new File("orders.txt"));
ArrayList<Order> orders = new ArrayList<Order>();
while (s.hasNext()){
type = s.nextLine();
}
switch(type) {
case 1: type = NonProfitOrder();
break;
case 2: type = RegularOrder();
break;
case 3: type = OverseasOrder();
return orders;
}
}
I can't figure out how to do this properly as it still says
readOrders can't be resolved to a type.
As well as other issues with the first readOrders.
I updated my code with somewhat of a switch state, that doesn't work of. Instead of case 1,2,3 should I be using N,O,R or how would I refer to each type of order? Also I'm having "type mismatch" error but I'm having trouble fixing it.
You are not correctly initialising your ArrayList and read orders method. This code here is not correct, the method ends after the ; and does nothing and the rest is invalid
ArrayList<Order> readOrders (String fileName); {
ArrayList<Order> orders2 = new readOrders("orders.txt");
}
What you are needing to do is create a method readOrder like the following See this post on how to read in the file. Except in your case you will need to do more work in the loop to create the Order object
public static ArrayList<Order> readOrders (String fileName){
ArrayList<Order> orders = new ArrayList<Order>();
//Read in lines from your file
//Decide which type of order it is and create it
//Add it to the list
//Repeat until end of file
return orders
}
Then in your main method
public static void main(String[] args) {
ArrayList<Order> loadedOrders = readOrders("orders.txt");
//... rest of your code
}
ADDITIONAL EDIT
To insert them into the list do something like this
char firstChar = //Read in the first character of the line from the file
Order anOrder;
switch(firstChar)
{
case 'N':
anOrder = new NonProfitOrder(); //adding arguments to construtor as needed
break;
case 'R':
anOrder = new RegularOrder();
break;
default:
anOrder = new Order();
break;
}
loadedOrders.add(anOrder);
Then when reading, depending on what you need to do with the order you will might need to use instanceof and cast. However you can avoid this if in the base class you have the methods declared and only override them in the sub classes, then when you read from the List, the method is looked for in the subclass first, if its not found then is looked for in the base class, then if its not in the base class obviously you will get an error. This where having an abstract base class is useful and means you can avoid doing this
Order ord = orders.get(anIndex)
if(ord instanceof NonProfitOrder)
((NonProfitOrder)ord).aNonprofitOrderSpecificMethod()
else if (ord instanceof RegularOrder())
((RegularOrder)ord).aRegularOrderSpecificMethod();
//.....
Related
"Write a Java program to simulate an online store. The program should begin
by displaying a list of products and their prices. There should be a minimum of 4
products offered.
My code is below, it works without the strings but I need to have names for the cakes(display names and prices)
import java.util.Scanner;
public class Main
{
public static void main(String[] args) {
Scanner input= new Scanner(System.in)
int cakeNo = 0;
double cake1;
double cake2;
double cake3;
double cake4;
double cake5;
int quantity;
double totalSales = 0;
while(cakeNo !=0 )
System.out.println("Enter cake number 1-5");
cakeNo=input.nextInt();
System.out.println("Enter quantity");
quantity = input.nextInt();
switch (cakeNo){
case 1: cake1 = 3.70;
totalSales+=(3.70*quantity);
break;
case 2: cake2 = 4.20;
totalSales+=(4.20*quantity);
break;
case 3: cake3 = 4.50;
totalSales+=(4.50*quantity);
break;
case 4: cake4 = 5.00;
totalSales+=(5.00*quantity);
break;
case 5: cake5 = 5.50;
totalSales+=(5.50*quantity);
break;
}
System.out.println(totalSales);
}
}
Thank you so much for reading! Please help if you have an idea.
Well there are a few things wrong in your code that you should take care first.
First: The first 5 string are wrongly defined. It should be like this String cake1 = "Angel cake" and so on.
Second: The strings and doubles have the same names you cannot do that. You need to have something like String cake1Name = "Name" and double cake1Price = price this way you have two distinct properties for everycake.
Third: Right now the code doesn't even enters the while loop. Since cakeNo starts with 0 and the condition in your while loop is cakeNo != 0 right on before the first loop this condition will be tested and it will be false meaning that the loop code won't be executed and will jump to the end of the program.
After this fixes there is still a little problem. After you get the input from the user if said input is 0 meaning that he wants to leave the program will still ask him for a quantity. You need to add/change something that breaks the loop when this conditions is true. I don't want to give you code but I hope this answer can help you good luck :)
This is what I would do:
public class Main {
LinkedList<Product> cart = new LinkedList<Product> ();
Scanner scanner = new Scanner(System.in);
double tax = 7.5;
boolean done = false;
public Main() {
cart.add(new Product("Cake 1", 3.70));
cart.add(new Product("Cake 2", 4.20));
cart.add(new Product("Cake 3", 4.50));
cart.add(new Product("Cake 4", 5.00));
cart.add(new Product("Cake 5", 5.50));
}
public void displayCart() {
for (int i = 0; i < cart.size(); i++) {
switch (cart.get(i).quantitySelected){
case 0:
System.out.println(i + ": " + cart.get(i).name + " none selected");
break;
default:
System.out.println(i + ": " + cart.get(i).name + " selected: " + cart.get(i).quantitySelected);
break;
}
}
}
public void addToCart(int product, int amount) {
cart.get(product).select(amount);
}
public void getSelection() {
int productSelected;
System.out.println("enter a product value or FINNISHED to end: ");
try {
productSelected = scanner.nextInt();
} catch (InputMismatchException e) {
done = true;
return;
}
System.out.println("enter amount to select: ");
int amount = scanner.nextInt();
cart.get(productSelected).select(amount);
}
public double getSubtotal() {
double cost = 0.00;
for (Product product : cart) {
cost += product.cost * product.quantitySelected;
}
return cost;
}
public double getTotal() {
return getSubtotal() + getSubtotal()*tax;
}
public void finnishPurchase() {
System.out.println("---------------------");
System.out.println("subtotal: " + getSubtotal());
System.out.println("tax: " + tax);
System.out.println("total: " + getTotal());
}
public static void main(String[] args) {
Main store = new Main();
while (!store.done) {
store.displayCart();
store.getSelection();
}
store.finnishPurchase();
}
}
public class Product {
String name;
double cost;
int quantitySelected = 0;
public Product(String name, double cost) {
this.name = name;
this.cost = cost;
}
public void select(int quantity) {
quantitySelected = quantity;
}
}
I am a beginner in java and I tried doing this activity but I am so confused on the determineClass instance. When I run the code below, the 'classification' is not called.
Instructions:
The computeWeekly method is an instance method that should compute the weekly salary using the formula: fixedSalary * daysWorked * bonusRate. Whatever the computed weekly salary is, the determineClass method takes the value as an input and determines what classification the employee is (use your conditional structure research here).
The displayEmployee method just prints out all the attributes of each object. Name, Classification, Fixed Salary, WeeklyGross, and Bonus Rate. The appropriate classification should be reflected depending on the computed weekly gross.
public class Employee{
public String name;
public char classification;
private double fixedSalary;
private double weeklyGross;
private double bonusRate;
//constructor without a parameter
public Employee(){
this.name = "Paul";
this.fixedSalary = 250;
this.bonusRate = 5;
}
//compute weekly salary
private double computeWeekly(double fixedSalary, int daysWorked, double bonusRate){
weeklyGross = fixedSalary * daysWorked * bonusRate;
return weeklyGross;
}
//take the weekly salary as input and determine what's the classification of the employee
private char determineClass(double computeWeekly){
if (computeWeekly >= 0){
classification = 'A';
}else if (computeWeekly >= 2000){
classification = 'B';
}else if (computeWeekly >= 2500){
classification = 'C';
}else if (computeWeekly >= 3000){
classification = 'D';
}else if (computeWeekly >= 3500){
classification = 'E';
}else{
classification = 'F';
}
return classification;
}
//display information
public void displayEmployee(){
System.out.println("Name: " + name);
System.out.println("Classification: " + classification);
System.out.println("Fixed Salary: " + fixedSalary);
System.out.println("Weekly Gross: " + weeklyGross);
System.out.println("Bonus Rate: " + bonusRate);
}
//main
public static void main(String[] args){
Employee employee1 = new Employee();
employee1.computeWeekly(300, 7, 10);
employee1.displayEmployee();
}
}
Result:
Name: Paul
Classification:
Fixed Salary: 250.0
Weekly Gross: 21000.0
Bonus Rate: 5.0
How can I set the value for the classification applying the conditional structure?
What is with
employee1.classification=employee1.determineClass(employee1.getWeeklyGross());
therefore you have to implement the function:
public double getWeeklyGross(){
return WeeklyGross;
}
You can set the value of classification with the following expression:
classification = determineClass(weeklyGross);
This has to be implemented between those two lines of code.
employee1.computeWeekly(300, 7, 10);
employee1.displayEmployee();
okay so to the preface the situation. I have been given an assignment with various tasks. So far I have created a Canteen Account(which will be shown below), a main menu class, and now I have to make another class which inherits from Canteen Account, called StaffAccount. A StaffAccount object should contain the following additional property :
discountRate - the rate (percentage) discount applied to all purchases
A StaffAccount object should contain the following additional methods:
(i) StaffAccount (String newId, String newName, double discountRate)
A constructor method to initialise the StaffAccount object’s properties via the three parameters.
In the staff account I am having issues with a method called PayForMeal(which is an overridden method) which in the assignment brief has the purpose of:
A method to record the cost of a meal. The balance on a StaffAccount object should be amended to reflect discount on the cost of a meal (if the cost does not exceed available balance).
If the cost exceeds the balance then an Exception will be thrown to warn the customer they must topUp their balance – if the customer is within their credit limit a negative value will be recorded in the balance and the status of the account changed to show that the customer is using credit.
No discount should be applied if the customer is using credit.
So my issue is, how do I make a staff account using the constructor given to me, and then use the payForMeal overridden method to apply a discount to the amount a meal costs, then take the discounted amount away from a balance which is not there because it is not in the constructor for the StaffAccount, but it is in the constructor for the CanteenAccount. The classes are below, i just want to know if this is possible or am I being dumb
//////CANTEEN ACCOUNT \\\\\\\\
public class CanteenAcc
{
private String customerId;
private String name;
private double balance;
private static double minTopup = 2.00;
private String status;
private static double creditLimit = 5.00;
private static int transCount;
/**
* Constructor to create a Canteen account object using three parameters
* #param newId - String
* #param newName - String
* #param newBalance - Double
*/
public CanteenAcc(String newId, String newName, double newBalance)
{
this.customerId = newId;
this.name = newName;
this.balance = newBalance;
}
public CanteenAcc(String newId, String newName)
{
this.customerId = newId;
this.name = newName;
}
//BEFORE EVERY METHOD AND CLASS YOU SHOULD HAVE JAVADOC COMMENTS.
public void topUp(double depositAmount)
{
if(depositAmount > 0)
{
this.balance += depositAmount;
this.status = "Valid";
}else
{
this.status = "Invalid";
}
}
public void payForMeal(double amount) throws Exception
{
if(balance - amount < 0 && amount - balance <= creditLimit)
{
this.status = "Using Credit";
double newBalance = balance - amount;
balance = newBalance;
throw new Exception("\n\n-----------------------------\n"
+ "You must top-up your balance\n"
+ "Your new balance is: "+ balance + " GBP" +"\n"
+ "You are: " + status + "\n"
+ "-----------------------------\n");
}
else if(amount > creditLimit && balance < amount)
{
throw new Exception("\n\n------------------------------\n"
+ "Cost exceeds the credit limit."
+ "\n------------------------------\n");
}
else
{
double newBalance = balance - amount;
balance = newBalance;
transCount++;
}
}
public String displayAccountDetails()
{
StringBuilder ad = new StringBuilder();
ad.append("------------------------\n");
ad.append("****Account Details****\n");
ad.append("------------------------\n");
ad.append("\n");
ad.append("****Customer ID****: \n" + customerId + "\n");
ad.append("\n");
ad.append("****Name****: \n" + name + "\n");
ad.append("------------------------\n");
ad.append("\n");
return ad.toString();
}
public String getStatistics()
{
StringBuilder as = new StringBuilder();
as.append("------------------------\n");
as.append(" CANTEEN ACCOUNT \n");
as.append("------------------------\n");
as.append("\n");
as.append("****Transaction Count****\n");
as.append(transCount + "\n");
as.append("\n");
as.append("****Account Balance****\n");
as.append(balance + "\n");
as.append("\n");
as.append("***Account Status****\n");
as.append(status + "\n");
as.append("------------------------\n");
return as.toString();
}
public double getBalance()
{
return balance;
}
public double getCreditLimt()
{
return creditLimit;
}
public double getMinTopup()
{
return minTopup;
}
public String getStatus()
{
return status;
}
public static void updateCreditLimit(double newLimit)
{
creditLimit = newLimit;
}
public static void updateMinTopup(double newTopup)
{
minTopup = newTopup;
}
}
////////MAIN METHOD////////////////////////
public class Test
{
public static void main(String[] args) {
String menuItems[] = {"1. Top up account ", "2. Pay for meal ", "3. Display Account Status",
"4. Display Account Balance ", "5. Display Account Details ",
"6. Update credit limit ", "7. Update Minimum top-up ", "8. Exit program"};
Menu myMenu = new Menu("Holiday Account", menuItems) ;
int choice;
Scanner keyb = new Scanner(System.in);
choice = myMenu.getChoice() ;
do{
choice = myMenu.getChoice();
//CanteenAcc Employee = new CanteenAcc("A01PL", "Patrick", 2);
CanteenAcc Employee2 = new StaffAccount("blah", "blah", 0.25);
switch (choice)
{
case 1 : System.out.println("How much would you like to top-up: ");
double deposit = keyb.nextDouble();
Employee2.topUp(deposit);
System.out.println("Your balance is: £" + Employee2.getBalance());
break ;
case 2: System.out.println("Input how much your meal costs: ");
try {
double amount = keyb.nextDouble();
Employee2.payForMeal(amount);
System.out.println("Your meal cost: " + amount);
} catch(Exception ex)
{
System.out.println(ex.toString());
}
System.out.println("Your balance is: £" + Employee2.getBalance());
break ;
case 3: System.out.println(Employee2.getStatus());
break;
case 4: System.out.println("£" + Employee2.getBalance());
break;
case 5: System.out.println(Employee.displayAccountDetails());
break;
case 6: System.out.println("What amount would you like the new limit to be: ");
double newLimit = keyb.nextDouble();
CanteenAcc.updateCreditLimit(newLimit);
System.out.println("The new credit limit is: " + newLimit);
case 7: System.out.println("What amount would you like the new limit to be: ");
double newMinTopup = keyb.nextDouble();
CanteenAcc.updateMinTopup(newMinTopup);
System.out.println("The new minimum topUp is: " + newMinTopup);
case 8: System.exit(0);
}
}//End DoWhile
while(choice != 8);
}
}
////STAFF ACCOUNT///////
public class StaffAccount extends CanteenAcc
{
private double discountRate;
public StaffAccount(String newId, String newName, double discountRate)
{
super (newId, newName);
this.discountRate = 0.25;
balance = 0;
}
public void setDiscountRate(double rate)
{
discountRate = rate;
}
public double getDiscountRate()
{
return discountRate;
}
public void payForMeal(double amount) throws Exception
{
amount = amount/discountRate;
super.payForMeal(amount);
}
}
OK:
You've got a CanteenAcc: good. You've also got a StaffAccount that inherits from CanteenAcc. Also good.
You should annotate StaffAccount.payForMeal() with #Override: When do you use Java's #Override annotation and why?
Your variable names should all start with lower case, e.g. CanteenAcc employee2 = new StaffAccount("blah", "blah", 0.25);.
updateCreditLimit() and updateMinTopup() should NOT be static (because each different object might have a different value): Java: when to use static methods
... Finally ...
With CanteenAcc employee = new CanteenAcc("A01PL", "Patrick", 2);, then employee.payForMeal() will have the "CanteenAcc" behavior.
With CanteenAcc employee2 = new StaffAccount("blah", "blah", 0.25);, then employee2.payForMeal() will have the "StaffAccount" behavior.
Q: So what's the problem? Does that help clarify ... or does it just confuse things further?
There are a number of things "wrong" with the code you posted. I hope you have an IDE, and step through the debugger with sample test values.
But to your original question:
You're on the right track.
There are a couple of "minor" issues I noted above.
I'm not sure why you're worried about "constructors". The way object oriented languages (like Java) work - if you define the right base classes, and appropriately "specialize" behavior in subclasses, then - through the magic of "inheritence" - everything "just works".
I modified your code slightly, and wrote a different "test driver". Here is the code, and the output:
StaffAccount.java
package com.example;
public class StaffAccount extends CanteenAccount {
private double discountRate;
public StaffAccount(String newId, String newName, double discountRate) {
super(newId, newName);
this.discountRate = discountRate; // Set this to "discountRate", instead of hard-coding 0.25
// You'll note that "balance" is implicitly set to "0.0" in the base class
}
public void setDiscountRate(double rate) {
discountRate = rate;
}
public double getDiscountRate() {
return discountRate;
}
#Override
public void payForMeal(double amount) throws Exception {
amount = amount / discountRate;
super.payForMeal(amount);
}
}
TestAccount.java
package com.example;
/**
* Test driver
* In a "real" application, I would implement these as a suite of JUnit tests
*/
public class TestAccount {
private static void buyAMeal (CanteenAccount person, double cost) {
try {
person.payForMeal(cost);
} catch (Exception e) {
System.out.println ("ERROR: " + e.getMessage());
}
}
public static void main(String[] args) {
System.out.println (">>Creating employee (\"CanteenAccount\" and employee2 (\"StaffAccount\") objects...");
CanteenAccount employee = new CanteenAccount("A01PL", "Patrick", 2);
CanteenAccount employee2 = new StaffAccount("blah", "blah", 0.25);
System.out.println (">>Checking initial balances...");
System.out.println (" employee balance=" + employee.getBalance() + ", creditLimit=" + employee.getCreditLimit());
System.out.println (" employee2 balance=" + employee2.getBalance() + ", creditLimit=" + employee2.getCreditLimit());
System.out.println (">>Buying a $5.00 meal...");
System.out.println (" employee...");
buyAMeal (employee, 5.00);
System.out.println (" employee balance=" + employee.getBalance() + ", creditLimit=" + employee.getCreditLimit());
System.out.println (" employee2...");
buyAMeal (employee2, 5.00);
System.out.println (" employee2 balance=" + employee2.getBalance() + ", creditLimit=" + employee2.getCreditLimit());
System.out.println (">>Add $5.00 and buy another $5.00 meal...");
System.out.println (" employee...");
employee.topUp(5.0);
buyAMeal (employee, 5.00);
System.out.println (" employee balance=" + employee.getBalance() + ", creditLimit=" + employee.getCreditLimit());
System.out.println (" employee2...");
employee2.topUp(5.0);
buyAMeal (employee2, 5.00);
System.out.println (" employee2 balance=" + employee2.getBalance() + ", creditLimit=" + employee2.getCreditLimit());
}
}
Sample output:
>>Creating employee ("CanteenAccount" and employee2 ("StaffAccount") objects...
>>Checking initial balances...
employee balance=2.0, creditLimit=5.0
employee2 balance=0.0, creditLimit=5.0
>>Buying a $5.00 meal...
employee...
ERROR:
-----------------------------
You must top-up your balance
Your new balance is: -3.0 GBP
You are: Using Credit
-----------------------------
employee balance=-3.0, creditLimit=5.0
employee2...
ERROR:
------------------------------
Cost exceeds the credit limit.
------------------------------
employee2 balance=0.0, creditLimit=5.0
>>Add $5.00 and buy another $5.00 meal...
employee...
ERROR:
-----------------------------
You must top-up your balance
Your new balance is: -3.0 GBP
You are: Using Credit
-----------------------------
employee balance=-3.0, creditLimit=5.0
employee2...
ERROR:
------------------------------
Cost exceeds the credit limit.
------------------------------
employee2 balance=5.0, creditLimit=5.0
I am a complete beginner in programming and I'm working on a program for my mother that tracks her employee's monetary intake through a "horse race", with each employee having a horse and the program tracking their input to a UI made to look like a racetrack. After the help from my last inquiry, I've greatly simplified my mess of code but I am now faced with a new problem in that, after sorting the values largest to smallest, I have no way of associating the sorted values with the correct horse. I understand this explanation is confusing so I hope my code will do most of the talking for me here.
I honestly have no idea where to start with this. As I said in my last inquiry, I'm a complete beginner and severely lack the terminology or knowledge to find an answer here.
public class HorseRace {
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String horse1 = "#5 Gitty-Up";
String horse2 = "#7 Lady Simmons";
String horse3 = "#6 Burning Peanutbutter";
String horse4 = "#10 White Lightning";
String horse5 = "#3 Bella";
String horse6 = "#1 Meg The Stallion";
float h1val;
float h2val;
float h3val;
float h4val;
float h5val;
float h6val;
System.out.println("Input amount for " + horse1 + ":");
h1val = sc.nextFloat();
System.out.println("Input amount for " + horse2 + ":");
h2val = sc.nextFloat();
System.out.println("Input amount for " + horse3 + ":");
h3val = sc.nextFloat();
System.out.println("Input amount for " + horse4 + ":");
h4val = sc.nextFloat();
System.out.println("Input amount for " + horse5 + ":");
h5val = sc.nextFloat();
System.out.println("Input amount for " + horse6 + ":");
h6val = sc.nextFloat();
Float[] values = new Float[]{h1val, h2val, h3val, h4val, h5val, h6val};
Arrays.sort(values, Collections.reverseOrder());
//currently displays horses with the wrong number. Need a way to tie the horse name strings to their respective float elements
System.out.println("The current race progress is :");
System.out.println(horse1 + " with $" + values[0]);
System.out.println(horse2 + " with $" + values[1]);
System.out.println(horse3 + " with $" + values[2]);
System.out.println(horse4 + " with $" + values[3]);
System.out.println(horse5 + " with $" + values[4]);
System.out.println(horse6 + " with $" + values[5]);
}
}
my desired result is printing the correct horse with the correct value. For example, if I put that #5 brought in $11 and #7 brought in $14, the program would print that #7 is in the lead with $14 and #5 is in second place with $11.
Currently, the program always prints #5 as being in the lead with the highest value, #7 being in second with the second highest, etc.
I understand this is because I am hard calling the horse1-horse6 values meaning they don't change, but these are acting more as placeholders while I figure out how to associate the right horse with the right value
This is where you should create a Horse class and store the data as instances of Horse.
class Horse {
private String name;
private float value;
public String getName() { return name; }
public float getValue() { return value; }
public void setName(String name) { this.name = name; }
public void setValue(float value) { this.value = value; }
}
And then in your main method:
Horse[] horses = new Horse[6] {
new Horse(), new Horse(), new Horse(), new Horse(), new Horse(), new Horse()
};
horses[0].setName("#5 Gitty-Up");
horses[1].setName("#7 Lady Simmons");
horses[2].setName("#6 Burning Peanutbutter");
// and so on...
// you should use a for loop here instead of writing similar lines over and over again!
for (int i = 0 ; i < 6 ; i++) {
System.out.println("Input amount for " + horses[i].getName() + ":");
horses[i].setValue(sc.nextFloat());
}
Arrays.sort(horses, Comparator.comparingDouble(Horse::getValue).reversed());
System.out.println("The current race progress is :");
for (int i = 0 ; i < 6 ; i++) {
System.out.println(horses[i].getName() + " with $" + horses[i].getValue());
}
By using a class, you are essentially grouping data that belongs together, together. On the line Arrays.sort(horses, Comparator.comparingDouble(Horse::getValue).reversed());, I am sorting the whole array of horses together, by their values.
If the concepts of classes and objects are new to you, that just means it's time to learn about some new concepts. Classes and objects are very important.
Step 1, create a Horse class. It should have two fields, amount and name. It should implement Comparable because you want to sort it. And looking at your desired output, I would override toString().
class Horse implements Comparable<Horse> {
private String name;
private float amount;
public Horse(String name, float amount) {
this.name = name;
this.amount = amount;
}
#Override
public String toString() {
return String.format("%s with $%.2f", name, amount);
}
#Override
public int compareTo(Horse o) {
return Comparator.comparing((Horse h) -> h.amount)
.thenComparing((Horse h) -> h.name).compare(this, o);
}
}
Step 2, create an array of horseNames and iterate that populating an array of Horses (with amounts). Then sort it, and I would prefer Comparator.reverseOrder() to Collection.reverseOrder() when sorting an array.
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
String[] horseNames = { "#5 Gitty-Up", "#7 Lady Simmons",
"#6 Burning Peanutbutter", "#10 White Lightning",
"#3 Bella", "#1 Meg The Stallion" };
Horse[] horses = new Horse[horseNames.length];
for (int i = 0; i < horseNames.length; i++) {
System.out.printf("Input amount for %s:%n", horseNames[i]);
float amt = sc.nextFloat();
horses[i] = new Horse(horseNames[i], amt);
}
Arrays.sort(horses, Comparator.reverseOrder());
System.out.println("The current race progress is :");
for (int i = 0; i < horses.length; i++) {
System.out.println(horses[i]);
}
}
I want to print what I've ordered in the starters method with the quantity when printing the bill. Any suggestions as to how I will do it? I have only written an instance of my program since it the entire problem is very large.
Thanks in advance.
static void Bill()
{
System.out.println("\f");
System.out.println("*********************************************************");
System.out.println("*********************************************************");
System.out.println("**************************BILL***************************");
System.out.println(ob);
System.out.println("Your phone number - "+j);
int Z = (int)(Math.random()*10000000);
System.out.println("Bill number is "+Z);
System.out.println("The total bill amount is Rs."+sum);
System.out.println();
System.out.println("Hope you enjoyed. Visit us again soon!");
Food=0;
}
static void Starters()
{
System.out.println("You have selected Starters");
System.out.println();
System.out.println("1. Spring Rolls - Rs 350");
System.out.println("2. Onion Rings - Rs 350");
System.out.println("3. Fried Raviolli - Rs 400");
System.out.println("4. Gorgonzola - Rs 400");
System.out.println("5. Fresh Ricotta Crostini - Rs 475");
System.out.println("6. Potato Fritters - Rs 500");
System.out.println();
System.out.println("Enter your desired option");
starterOption=sc.nextInt();
System.out.println("Enter quantity");
quantity=sc.nextInt();
switch(starterOption)
{
case 1:
s1 = quantity * 350;
break;
case 2:
s2 = quantity * 350;
break;
case 3:
s3 = quantity * 400;
break;
case 4:
s4 = quantity * 400;
break;
case 5:
s5 = quantity * 475;
break;
case 6:
s6 = quantity * 500;
break;
default:
System.out.println("You haven't ordered anything");
break;
}
System.out.println("Do you want to order anything else? Y/N");
A = sc1.next();
if(A.equalsIgnoreCase("Y"))
{
System.out.println("Do you want to order from the same section? Y/N ");
F=sc.next();
if(F.equalsIgnoreCase("Y"))
{
sum=s1+s2+s3+s4+s5+s6;
Starters();
}
else
{
sum=s1+s2+s3+s4+s5+s6;
Food_Items();
}
}
else
{
sum=s1+s2+s3+s4+s5+s6;
Bill();
}
}
As mentioned above: this is a very long code for a really simple problem.
When you want to print what was ordered, then you have to save it in a variable, e.g. an array. Or as suggested in a Collection e.g. a List. You can expand your code in the same manner you did it. But it's strongly recommended that you refine your code.
I suggest using a HashMap, read the example in the tutorial in this link
A possible solution to your issue could be :-
Declare variable in the class, preferable 'private'
private static HashMap<String, Integer> Starters = new HashMap<String, Integer>();
private static HashMap<String, Integer> Orders = new HashMap<String, Integer>();
Initialize these using some Init Function or the Constructor of the class with all the possible values for Startres
Starters.put("Spring Rolls", 350);
Starters.put("Onion Rings", 400);
in the Starters() Function you could use (stripped down sample)
System.out.println("You have selected Starters");
System.out.println();
int i = 1;
String[] mystarters = Starters.keySet().toArray(new String[Starters.keySet().size()]);
for (String starter : mystarters) {
System.out.println(i++ + ". " + starter + " : Rs. " + Starters.get(starter));
}
System.out.println("Enter your desired option");
//get option
System.out.println("Enter quantity");
//get quantity
// I am using s. as a prefix for starters, for Main course you could use m. or mc. or something
Orders.put("s." + mystarters[option - 1], quantity);
Of course, you could get the Quantity if this Starter already exists in the order and add to the existing quantity, or ask if it needs to be overwritten.
// example
if(Orders.containsKey("s." + mystarters[option - 1]))
Orders.put(("s." + mystarters[option - 1]), Orders.get("s." + mystarters[option - 1])+quantity);
else
Orders.put("s." + mystarters[option - 1], quantity);
In Bill , you could use the following :-
int sum = 0;
for (String orderItem : Orders.keySet()) {
int price = 0;
int quant = Orders.get(orderItem);
if (orderItem.startsWith("s.")) {
orderItem = orderItem.substring(2);
price = Starters.get(orderItem);
System.out.println(orderItem + " x " + quant + " = Rs. " + price * quant);
}
sum += price * quant;
}
System.out.println("Total Price : Rs." + sum);
There are several improvement you could do to your code. You have to store what you have already order, if you want to show all the elements on the bill. Each time you order, you can add the element to a List
You need to store objects in the list, so you could create some objects for your dishes. Enums seems to be appropiate to your application, this could be some example for the starters:
enum Starters {
SPRING_ROLLS("Spring Rolls", "Rs 350", 5),
FRIED_RAVIOLLI("Fried Raviolli", "Rs 400", 9),
... // All other starters...
String name;
String code;
int price;
public Starters(String name, String code, String price) {
this.name = name;
this.code = code;
this.price = price;
}
public String getName() {
return name;
}
public String getCode(){
return code;
}
public int getPrice(){
return price;
}
}
Then you display your menus like this:
for (Starters starter : Starters.values()) {
System.out.println(starter.getName() + " " starter.getCode()); // Just an example, modify to fit your format
}
You are going to have different types of enums and you want to add objects of the same type to the list. You can use an interface for this and make all enums to implement the interface:
public interface Orderable {
public String getName();
public String getCode();
public String getPrice();
}
You can initialize the list like this:
List<Orderable> orders = new ArrayList<>();
And add elements to the list like this (The enums need to implement the Orderable interface):
orders.add(Starters.SPRING_ROLLS);
order.add(Desserts.CHEESE_CAKE);
...
When you want to display the bill, you can iterate over the list and display the orders:
int totalPrice = 0;
for (Orderable order : orders) {
System.out.println(order.getName() + " - " order.getPrice());
totalPrice += order.getPrice();
}
System.out.println("Total price: ");