I am creating a flight controller application. A bit of functionality that i want is to be able to tell the user what the next flight is according to a specific airline. I have a hash map which stores strings and planes. In my plane class i am implementing Comparable and i have the compareTo method. Could anyone help me achieve using the compareTo method to arrange the planes in descending order to show the next flight. I want to arrange the flights by the variable overdue.
This is the case in the MainApp that i have to use the compareTo on
switch (nextChoice)
{
case 1:
airlineMap.printAirline("Aer Lingus");
break;
case 2:
airlineMap.printAirline("Brittish Airways");
break;
case 3:
airlineMap.printAirline("Eithad");
break;
case 4:
airlineMap.printAirline("Iberia");
break;
case 5:
airlineMap.printAirline("Quantas");
break;
I hope to add the descending order to a airline print: airlineMap.printAirline("Aer Lingus");
Here is my Plane class:
import java.util.LinkedList;
public class Plane implements Comparable
{
private String flightNumber;
public String airlineName;
private double fuelRemaining;
private int overdue;
private int passengerNumber;
private AIRPLANETYPE planeType;
public enum AIRPLANETYPE
{
AIRBUS("1"), CORPORATE("2"), PRIVATE("3");
private String planeName;
private AIRPLANETYPE(String planeName)
{
this.planeName = planeName;
}
public String getPlaneName()
{
return this.planeName;
}
}
public Plane(String flightNumber, String airlineName, double fuelRemaining, int overdue, int passengerNumber, AIRPLANETYPE planeType) {
this.flightNumber = flightNumber;
this.airlineName = airlineName;
this.fuelRemaining = fuelRemaining;
this.passengerNumber = passengerNumber;
this.overdue = overdue;
this.planeType = planeType;
}
public String getAirlineName() {
return airlineName;
}
public void setAirlineName(String airlineName) {
this.airlineName = airlineName;
}
public void setOverdue(int overdue) {
this.overdue = overdue;
}
public int getOverdue(){
return overdue;
}
public String getFlightNumber() {
return flightNumber;
}
public void setFlightNumber(String flightNumber) {
this.flightNumber = flightNumber;
}
public double getFuelRemaining() {
return fuelRemaining;
}
public void setFuelRemaining(double fuelRemaining) {
this.fuelRemaining = fuelRemaining;
}
public int getPassengerNumber() {
return passengerNumber;
}
public void setPassengerNumber(int passengerNumber) {
this.passengerNumber = passengerNumber;
}
public AIRPLANETYPE getPlaneType() {
return planeType;
}
public void setPlaneType(AIRPLANETYPE planeType) {
this.planeType = planeType;
}
public int compareTo(Object arg0) {
if((arg0 != null) && (arg0 instanceof Plane))
{
Plane p = (Plane) arg0;
return (int)Math.ceil(this.overdue - p.getOverdue());
}
return 0;
}
public String toString() {
return "Plane: flightNumber=" + flightNumber + "."
+ " airlineName=" + airlineName + "."
+ " fuelRemaining=" + fuelRemaining + " litres."
+ " overdue=" + overdue + " minutes."
+ " passengerNumber="+ passengerNumber + "."
+ " airplaneType=" + planeType + ".\n";
}
}
Since HashMap is unordered, you have two ways of going about sorting your planes:
Put them into a sorted container, or
Put them into an ArrayList<Plane> or an array Plane[], and sort that list or array
The first approach can be achieved with a TreeSet<Plane>: put your planes into the set, and iterate them in the "natural" order (i.e. the order consistent with their compareTo method).
The second approach requires copying the planes into a separate container or an array, and then using the sort method (or the Arrays.sort static method if it is an array) to order your planes in accordance with the order set by their compareTo implementation.
EDIT : (based on a comment) One way to deal with a problem of storing planes in a specific order inside a hash map is to make a hash map of tree sets, like this:
Map<String,TreeSet<Plane>> airlineMap = new HashMap<String,TreeSet<Plane>>();
Once you add the planes to each airline, they would be maintained in the order based on your compareTo implementation. with a TreeSet<Plane> in hand, you can easily find the next or the prior Plane by calling higher or lower.
You should use Math.signum rather than Math.ceil in your compareTo method.
Related
So, I'm still learning java and coding so the resolution may be obvious but I just can't see it.
I'm writing a code about stars and constelations for uni assignment.
package com.company;
import java.util.*;
public class Main {
static public class Constellation {
public List<Star> constellation;
public String nameOfConstellation;
public Constellation(List<Star> constellation, String nameOfConstellation) {
this.constellation = constellation;
this.nameOfConstellation = nameOfConstellation;
}
public List<Star> getConstellation() {
return constellation;
}
}
static public class Star {
// private String categoryName;
private Constellation constellation;
private String nameOfConstelation;
public String getCategoryName() {
int index = constellation.getConstellation().indexOf(this);
String categoryName;
return categoryName = GreekLetter.values[index] + " " + this.constellation.nameOfConstellation;
}
public void deleteStar(Star x) {
this.constellation.constellation.remove(x);
}
}
public enum GreekLetter {
alfa,
beta,
gamma,
delta,
epsilon,
dzeta,
eta;
static public final GreekLetter[] values = values();
}
public static void main(String[] args)
{
Star x = new Star();
List<Star> fishCon = new ArrayList<>();
Constellation Fish = new Constellation(fishCon, "Fish");
x.constellation=Fish;
fishCon.add(x);
x.getCategoryName();
Star y = new Star();
y.constellation=Fish;
fishCon.add(y);
y.getCategoryName();
x.deleteStar(x);
for (Star w : Fish.constellation)
{
System.out.println(w.getCategoryName());
}
}
}
My point is to Update field categoryName after deleting one star. categoryName value is set in order of adding another star. For example I have first star - the name will be Alfa + nameOfConstelation. Second star - Beta + nameOfConstelation. When I call method deleteStar() I want to update all categoyName of my stars in constelation. Calling methods in deleteStar() doesn't work probably due to add() in setCategoryName. I would really appreciate any hints!
Since this appears to be homework, I am not posting code in this answer but rather giving suggestions that can help you create your own workable code:
Create a class called Constellation that holds the Stars in an List<Star> starList = new ArrayList<>();
Give Constellation a public List<Star> getStarList() method
Give each Star a Constellation field to hold the Constellation that contains this Star
Give each Star a getCategoryName() method that gets the Constellation object, iterates through its starList using a for-loop until it finds the this Star, and then that returns the appropriate name based on the index of the Star in the list.
Thus, if a Star is removed from the starList, the category names of all the other Stars held by that Constellation will update automatically and dynamically
Also,
You can give Constellation a public void deleteStar(Star star) method where it removes the Star parameter from its starList
You can also give Star a public void deleteFromConstellation() method where it checks its Constellation field, constellation, and if not null, calls constellation.deleteStar(this); and then sets the constellation field to null
Get rid of the private String categoryName; field in Star. This should be a calculated field, meaning the public String getCategoryName() does not return a field, but a String based on code (as described above).
It first checks that Star's constellation field is not null
It then gets the index of the Star in the Constellation's starList (I have given my Constellation class a public int getIndexOfStar(Star star) method.
It then uses this, the GreekLetter class, and the constellation.getName() method to create a String to return
Done.
Since you've figured this out, this is another way to code it:
public class SkyMain {
public static void main(String[] args) {
Constellation fish = new Constellation("Fish");
Star x = new Star();
Star y = new Star();
fish.addStar(x);
fish.addStar(y);
System.out.println("before removing x");
System.out.println("x category name: " + x.getCategoryName());
System.out.println("y category name: " + y.getCategoryName());
System.out.println("fish constellation: " + fish);
fish.removeStar(x);
System.out.println();
System.out.println("after removing x");
System.out.println("x category name: " + x.getCategoryName());
System.out.println("y category name: " + y.getCategoryName());
System.out.println("fish constellation: " + fish);
}
}
public class Star {
private Constellation constellation;
public void setConstellation(Constellation constellation) {
this.constellation = constellation;
}
public void removeFromConstellation() {
if (constellation != null) {
constellation.removeStar(this);
}
}
public String getCategoryName() {
if (constellation != null) {
int index = constellation.getIndexOfStar(this);
return GreekLetter.getGreekLetter(index).getName() + " " + constellation.getName();
} else {
return "";
}
}
#Override
public String toString() {
return getCategoryName();
}
}
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Constellation implements Iterable<Star> {
private String name;
private List<Star> starList = new ArrayList<>();
public Constellation(String name) {
this.name = name;
}
public String getName() {
return name;
}
public List<Star> getStarList() {
return starList;
}
public void addStar(Star star) {
starList.add(star);
star.setConstellation(this);
}
public void removeStar(Star star) {
if (starList.contains(star)) {
starList.remove(star);
star.setConstellation(null);
}
}
public int getIndexOfStar(Star star) {
return starList.indexOf(star);
}
#Override
public Iterator<Star> iterator() {
return starList.iterator();
}
#Override
public String toString() {
return "Constellation [name=" + name + ", starList=" + starList + "]";
}
}
public enum GreekLetter
{
ALPHA("alpha", 0),
BETA("beta", 1),
GAMMA("gamma", 2),
DELTA("delta", 3),
EPSILON("epsilon", 4),
ZETA("zeta", 5),
ETA("eta", 6);
private String name;
private int index;
private GreekLetter(String name, int index) {
this.name = name;
this.index = index;
}
public String getName() {
return name;
}
public int getIndex() {
return index;
}
public static GreekLetter getGreekLetter(int index) {
if (index < 0 || index > values().length) {
throw new IllegalArgumentException("for index " + index);
} else {
return values()[index];
}
}
}
I'm writing a program in JAVA and I'm using a HashMap.
private HashMap<Integer,Plane> planes;
Plane is a class I have created:
public class Plane {
private int planeNumber;
private int departureTime;
private int arrivalTime;
private int flightDuration;
private int aerialDrops;
//constructors...
}
I then try to print all the components of the HashMap like that:
public void getAllAircrafts ()
{
Set set = planes.entrySet();
Iterator iterator = set.iterator();
while(iterator.hasNext()) {
Map.Entry mentry = (Map.Entry)iterator.next();
System.out.print("Aircraft ID is: "+ mentry.getKey() + " ");
System.out.println(mentry.getValue());
}
}
The problem is I want to print the values of all the variables that describe plane, but instead I get aircrafts.Plane#15db9742 from mentry.getValue(). How can I solve this problem?
You need to override and add a toString method for Plane class,
#Override
public String toString() {
return "Plane [planeNumber=" + planeNumber +
",departureTime=" + departureTime +
",arrivalTime=" + arrivalTime +
",flightDuration=" + flightDuration +
",aerialDrops=" + aerialDrops + "]";
}
Right now you are using toString method of Object class parent
A slight change would work fine as per you need :
public class Plane {
private int planeNumber;
private int planeNumber;
private int arrivalTime;
private int flightDuration;
private int aerialDrops;
public String toString()
{
return planeNumber +" "+planeNumber+" "+arrivalTime+" "+flightDuration+" "+aerialDrops
}
}
Right now I'm working on a basic java program that takes a few parameters into a constructor for a cup of coffee. That is easy enough but I'm having trouble creating a method for summing the number of coffee cups I've created.
So far this is the UseCoffee class I've created:
public class UsesCoffee{
public static void main(String args[]) {
System.out.println("cups created: " + Coffee.totalCups());
Coffee cup1 = new Coffee(350, "mint", true);
System.out.println("cup1: " + cup1);
Coffee cup2 = new Coffee(500, "mocha", false);
System.out.println("cups created: " + Coffee.totalCups());
System.out.println("cup2: " + cup2);
Coffee cup3 = new Coffee(350, "no flavour used", false);
cup3.doubleSize();
System.out.println("cup3: " + cup3);
Coffee cup4 = new Coffee(-10, "mocha", false);
System.out.println("cup4: " + cup4);
System.out.println("cups created: " + Coffee.totalCups());
if (Coffee.bigger(cup3,cup2))
System.out.println("cup3 is bigger than cup2");
if (Coffee.bigger(cup1,cup2))
System.out.println("cup1 is bigger than cup3");
if (Coffee.bigger(cup1,cup1))
System.out.println("cup1 is bigger than itself");
} // end main
} // end UsesCoffee
And this is the Coffee Class I've created:
public class Coffee {
private int coffeeVol;
private String coffeeFlav;
private boolean yesCream;
public Coffee(int volume, String flavour, boolean cream) {
this.coffeeFlav = flavour;
this.coffeeVol = volume;
this.yesCream = cream;
if (volume < 0) {
System.out.println("error: negative size. Defaultsize of 250 ml used");
coffeeVol = 250;
}
}
public String toString() {
return coffeeVol +"ml, " + coffeeFlav + ", " + yesCream;
} // end toString
public static int totalCups() {
//THIS IS WHERE I'M HAVING TROUBLE
}
public int doubleSize() {
coffeeVol = coffeeVol*2;
return coffeeVol;
}
}
Is there a way to sum the number of coffee cups? I'm truly lost in this respect, and any help is appreciated!
You could add a static variable to your Coffee class and increment it in your constructor.
Something like that:
public class Coffee {
private static int numberOfCups = 0;
private int coffeeVol;
private String coffeeFlav;
private boolean yesCream;
public Coffee(int volume, String flavour, boolean cream) {
this.coffeeFlav = flavour;
this.coffeeVol = volume;
this.yesCream = cream;
if (volume < 0) {
System.out.println("error: negative size. Defaultsize of 250 ml used");
coffeeVol = 250;
}
numberOfCups++;
}
public String toString() {
return coffeeVol +"ml, " + coffeeFlav + ", " + yesCream;
} // end toString
public static int totalCups() {
return numberOfCups;
}
public int doubleSize() {
coffeeVol = coffeeVol*2;
return coffeeVol;
}
public static boolean bigger(Coffee cup1, Coffee cup2) {
if (cup1.coffeeVol > cup2.coffeeVol) {
return true;
}
return false;
}
}
What you want to do is create a static field and increment it every time the constructor is called.
public class Coffee {
private static int totalCups;
// rest of the code ...
public Coffee(int volume, String flavour, boolean cream) {
totalCups++;
// rest of the code...
}
public static int getTotalCups() {
return totalCups;
}
}
// rest of the code ...
You want to make the field and method static because it will be shared by all instances of Coffee. You want to make totalCups a private field because of data encapsulation (you do not want to allow someone to change the total number of cups, which can only be modified logically via the constructor) and then retrieve it with a public getter method (which allows you to run additional data validation)
You might want to use something called an initialization block, and a static integer field to hold the current number of instances of your class. This is the best way of doing what you want, in my opinion.
public class Coffee
{
// Hold the number of instances.
private static int instances;
// This snippet of code will run whenever one of the //
// constructors below is called. All subclasses will //
// automatically inherit this too, by the way. //
{
instances++;
}
// first constructor
public Coffee() {}
// second constructor
public Coffee(int Foo) {}
// third constructor
public Coffee(double Bar) {}
// return the number of instances you have.
public static int totalCups()
{
return instances;
}
}
If you want to count the #/cups ... and you also want to compare each of the cups with each other ("which cup is largest") ... then you really ought to consider using a Collection.
EXAMPLE:
public class UsesCoffee{
public static void main(String args[]) {
ArrayList<Coffee> cups = new ArrayList<Coffee>();
System.out.println("cups created: " + cups.size());
cups.add(new Coffee(350, "mint", true));
cups.add(new Coffee(500, "mocha", false));
System.out.println("cups created: " + cups.size());
Coffee biggestCup = cups.get(0);
for (Coffee cup : cups) {
if (cup.coffeeVol > biggestCup.coffeeVol)
biggestCup = cup;
}
System.out.println("biggest cup is " + biggestCup.coffeeVol);
}
}
Main question:
Each flight has a number (this must start with letters EI and be followed by 3 digits), a day of the week the flight travels, a destination and the number of seats booked. Each flight will also have the standard responsibilities and the ability to calculate and return the number of free seats on a flight (assume each flight has a maximum of 10). You should use your imaginations to create one other flight responsibility that you think would be useful (this could also involve the creation of one or more new data items to support the responsibility).
This is what i have done so far:
public class Flight{
private String flightNo;
private date day;
private String
private int numberOfBookedSeats;
private int freeSeats=0;
private int passengerMeals;
private int mealsNeeded=0;
public Flight(){
}
public Flight(String flightNo, date day,String destination,int numberOfBookedSeats,int passengerMeals ){
this.flightNo= flightNo;
this.day = day;
this.destination= destination;
this.numeberOfSeats= numberOfSeats;
this.passengerMeals= passengerMeals;
}
public void setFlightNo(filghtNo f){
flightNo= f;
}
public String getFlightNo() {
return flightNo;
}
public void setDay(Day d) {
day= d;
}
public int getDay(){
return day;
}
public void setDestination(destination ds) {
destination = ds;
}
public int getDestination(){
return destination;
}
public void setNumeberOfSeats(numberOfSeats s){
numberOfSeats= s;
}
public int getNumeberOfSeats(){
return numeberOfSeats;
}
public void setPassengerMeals( passengerMeals pm){
passengerMeals= pm;
}
public int getPassengerMeals(){
return passengerMeals;
}
public int calculateFreeSeats(){
int maxSeatsNumbers = 10;
freeSeats = maxSeatsNumbers - numberOfBookedSeats;
return freeSeats;
}
public int calculateMealsNeeded(){
int staffMeals=5;
passengerMeals= numberOfBookedSeats;
mealsNeeded= staffMeals + passengerMeals;
return mealsNeeded;
}
}
Anint is not the correct class to store the flight number as, as it does not allow for the prefix characters or for the width to be specified. You could store it as a String, which would allow the prefix, and then do some validation and possibly padding to the numeric part, but what I would do is create a new type to represent the flight number.
This encapsulates the logic used to generate the flight number from the prefix String & int, making it more maintainable as the validation logic is just in one place, and it makes the code more understandable as your Flight class no longer has to contain logic to do with generating String flight numbers. It's a lot more clear in use, as well, because if you have a private final FlightNumber flightNumber member, you can use it in a String with something like "The flight number is " + flightNumber;.
See the following for what this type could look like:
Note this particular implementation uses Guava's Strings class - if you're not using this already it's probably not worth importing it just for this, so implement an equivalent yourself using String.format("%03d", ...) or similar, but if you've got Guava I think it looks cleaner.
import com.google.common.base.Strings;
public class FlightNumber {
private final String prefix;
private final int flightId;
public FlightNumber(String prefix, int flightId) {
if (flightId < 0 || flightId > 999) {
throw new IllegalArgumentException("Invalid Flight ID [" + flightId + "]");
}
this.prefix = prefix;
this.flightId = flightId;
}
#Override
public String toString() {
return prefix + Strings.padStart(String.valueOf(flightId), 3, '0');
}
}
If you wanted to extend this in the future, and your code suited this kind of design, you could then do something like the following:
public class AerLingusFlightNumber extends FlightNumber {
public AerLingusFlightNumber(int flightId) {
super("EI", flightId);
}
}
And:
public class BritishAirwaysFlightNumber extends FlightNumber {
public BritishAirwaysFlightNumber(int flightId) {
super("BA", flightId);
}
}
You should only create one public Constructor due to a Flight must have a FlightNumber (must be a String).
Also I would check at the body of the constructor the following:
if (!flightNumber.matchs("^EI\d{3}$")) {
throw new IllegalArgumentException("Invalid Flight number format.");
}
flightNo = flightNumber;
If you want your fight number to be alpha numeric then int is not the correct data type, you should use String and for validating that you could use the String method matches in conjunction with a regular expression.
Here is something you could start with:
class AirLine {
List<Flight> flights = new ArrayList<>();
public void addFlight(String flightNumber) {
flights.add(new Flight(flightNumber));
}
public List<Flight> getFlights() {
return flights;
}
}
class Flight {
String flightNumber;
public Flight(String flightNumber) {
setFlightNumber(flightNumber);
}
public String getFlightNumber() {
return flightNumber;
}
public void setFlightNumber(String flightNumber) {
if(flightNumber == null || ! flightNumber.matches("EI\\d{3}")) {
throw new IllegalArgumentException("invalid flight number: "
+ flightNumber);
}
this.flightNumber = flightNumber;
}
}
I'm not entirely sure how I would do this, here is my code:
public class PizzaMenu
{
static Map<String,Pizza> namedPizzas= new HashMap<String,Pizza>();
public static void main(String[] args)
{
}
public static void addItem(String name, Pizza pizza)
{
namedPizzas.put(name, pizza);
}
public String printMenu()
{
/*
String menuString="";
for (Every menu item)
{
//Add name of menu item to menuString with carriage return
//Add details of menu item (pizza.getInfo();) to menuString
}
*/
//return menuString
}
}
I would then call System.out.println(PizzaMenu.printMenu()) in another class. The sort of format I'm hoping to achieve is as follows:
/*
* PizzaName
* Details
*
* Next PizzaName in menu
* Details
*
* Next PizzaName in menu
* Details
*
*
*
*/
Am I maybe using the wrong data structure for this type of operation or is there a way of achieving this?
Here is the structure of the Pizza class (apologies for poor formatting):
public class Pizza
{
private double cost;
private Boolean veg;
private PizzaBase base;
private List<PizzaTopping> toppings = new ArrayList<PizzaTopping>();
public Pizza(PizzaBase base, PizzaTopping topping) //Constructor for pizza with 1 topping
{
setBase (base);
toppings.add(topping);
}
public Pizza(PizzaBase base, PizzaTopping topping, PizzaTopping topping2) //Constructor for pizza with 2 toppings
{
setBase (base);
toppings.add(topping);
toppings.add(topping2);
}
public Pizza(PizzaBase base, PizzaTopping topping, PizzaTopping topping2, PizzaTopping topping3) //Constructor for pizza with 3 toppings
{
setBase (base);
toppings.add(topping);
toppings.add(topping2);
toppings.add(topping3);
}
public double getCost()
{
return cost;
}
public void setCost(double cost)
{
this.cost = cost;
}
public PizzaBase getBase()
{
return base;
}
public void setBase(PizzaBase base)
{
this.base = base;
}
public List<PizzaTopping> getToppings()
{
return this.toppings;
}
public String getToppingsInfo()
{
String toppingInfo = "\n";
PizzaTopping t;
for (int i = 0; i<getToppings().size();i++)
{
t = toppings.get(i);
toppingInfo=toppingInfo+t.getInfo();
}
return toppingInfo;
}
public Boolean getVeg()
{
return veg;
}
public void setVeg(Boolean veg)
{
this.veg = veg;
}
public double calculateCost()
{
PizzaTopping p;
//Loop through all ingredients and add their costs to total cost
for (int i = 0; i<toppings.size();i++)
{
p = toppings.get(i);
cost+=p.getCost();
}
cost+=base.getCost(); //Add pizza base cost to total cost
return cost;
}
//Check if pizza is vegetarian depending upon its ingredients
public Boolean isVeg()
{
Boolean toppingCheck =true;
Boolean baseCheck = true;
PizzaTopping t; //Temporary value used to stored toppings being compared in for loop
//Check each topping and check if it's suitable for vegetarians
for (int i =0; i<toppings.size();i++)
{
while (toppingCheck == true)
{
t = toppings.get(i);
if (t.getVeg()==false)
{
toppingCheck = false;
}
}
}
//Check base to see if it's suitable for vegetarians
if (getBase().getVeg()==false)
{
baseCheck = false;
}
//Return value depending on if all ingredients are suitable for vegetarians
if (toppingCheck == true && baseCheck == true)
{
return true;
}
else return false;
}
public String getInfo()
{
String vegInfo;
if (this.isVeg()==true)
{
vegInfo = "Yes";
}
else vegInfo ="No";
return String.format("Toppings:%s\n"+"Base:\n%s"+"\nTotal Cost:\t£%.2f"+"\nSuitable for vegetarians: %s", getToppingsInfo(), getBase().getInfo(), calculateCost(), vegInfo);
//Return list of toppings, Total Price, vegetarian
}
}
Try this:
String menuString="";
for (Map.Entry<String, Pizza> pizzaItem : namedPizzas.entrySet()) {
menuString += pizzaItem.getKey() + "\n";
menuString += "\t" + pizzaItem.getValue().getInfo() + "\n\n";
}
public String printMenu()
{
String s ="";
for (String key: namedPizzas.keySet()){
s+= pizzaItem.getKey() + "\n";
s+= "\t" + pizzaItem.getValue().getInfo() + "\n\n";
}
return menuString
}
To address your question directly:
You need a set of keys. With a set of keys you can also get values. HashMap#keySet should work for this. You can loop through a set using a for each loop.
Then as you said, you need to build your string and return. Putting it together gives you:
public String printMenu()
{
String menuString = "";
for(String key : namedPizzas.keySet())
{
menuString += key + "\n" +
"\t" + namedPizzas.get(key).getInfo() + "\n\n";
}
return menuString;
}
I would also like to suggest a design improvement. You should be overriding the Object#toString method for things like this. The toString method will get automatically called when you try to print the object. This allows you to do: System.out.println(myPizzaMenu); instead of System.out.println(myPizzaMenu.printMenu());
The name printMenu is also misleading, so for that reason it's also bad.
Unfortunately, after switching the map to a list, it still didn't work. An hour later I found the bug causing it all! Thanks for everyone's answers, I will keep these methods in mind when I need to use maps again.
EDIT: Here is the new class structure for reference:
public class PizzaMenu
{
static List<Pizza> namedPizzas = new ArrayList<Pizza>();
public static void main(String[] args)
{
}
public static void addItem(String name, Pizza pizza)
{
pizza.setName(name.toLowerCase());
namedPizzas.add(pizza);
}
public static String printMenu()
{
String menuString="";
Pizza p;
//Collect all pizzas and add their information to string
for (int i =0; i<namedPizzas.size(); i++)
{
p = namedPizzas.get(i);
menuString+=p.getName().toUpperCase()+"\n"+p.getInfo()+"\n\n";
p.resetCost();
}
return menuString;
}
}