How to sum the number of instances of an object in Java? - java

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);
}
}

Related

How to implement strategy design pattern

Can anyone tell how can we implement Strategy design pattern in the following code. I have gone through various links but not fully clear about implementing it.
Question is: Calculate points and display the report in PDF or HTML using Strategy Design Pattern.
Below is the code already available. Customer, Movie and Rental are classes already created:
Customer.java
public class Customer {
private String _name;
private Vector _rentals = new Vector();
public Customer(String name) {
_name = name;
};
public void addRental(Rental arg) {
_rentals.addElement(arg);
}
public String getName() {
return _name;
}
public static void main(String[] args) {
Customer c = new Customer("ABC");
Movie m = new Movie("Title", 1);
Rental r = new Rental(m, 10);
c.addRental(r);
// Rental calculation
String s = c.statement();
System.out.println("s: " + s);
}
public String statement() {
double totalAmount = 0;
int frequentRenterPoints = 0;
Enumeration rentals = _rentals.elements();
String result = "Rental Record for " + getName() + "\n";
while (rentals.hasMoreElements()) {
double thisAmount = 0;
Rental each = (Rental) rentals.nextElement();
// determine amounts for each line
switch (each.getMovie().getPriceCode()) {
case Movie.REGULAR:
thisAmount += 2;
if (each.getDaysRented() > 2)
thisAmount += (each.getDaysRented() - 2) * 1.5;
break;
case Movie.NEW_RELEASE:
thisAmount += each.getDaysRented() * 3;
break;
case Movie.CHILDRENS:
thisAmount += 1.5;
if (each.getDaysRented() > 3)
thisAmount += (each.getDaysRented() - 3) * 1.5;
break;
} // add frequent
// renter points
frequentRenterPoints++;
// add bonus for a two day new release rental
if ((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) && each.getDaysRented() > 1)
frequentRenterPoints++;
// show figures for this rental
result += "\t" + each.getMovie().getTitle() + "\t" + String.valueOf(thisAmount) + "\n";
totalAmount += thisAmount;
}
// add footer lines
result += "Amount owed is " + String.valueOf(totalAmount) + "\n";
result += "You earned " + String.valueOf(frequentRenterPoints) + " frequent renter points";
return result;
}
}
Movie.java
public class Movie {
public static final int CHILDRENS = 2;
public static final int REGULAR = 0;
public static final int NEW_RELEASE = 1;
private String _title;
private int _priceCode;
public Movie(String title, int priceCode) {
_title = title;
_priceCode = priceCode;
}
public int getPriceCode() {
return _priceCode;
}
public void setPriceCode(int arg) {
_priceCode = arg;
}
public String getTitle() {
return _title;
};
}
Rental.java
public class Rental {
private Movie _movie;
private int _daysRented;
public Rental(Movie movie, int daysRented) {
_movie = movie;
_daysRented = daysRented;
}
public int getDaysRented() {
return _daysRented;
}
public Movie getMovie() {
return _movie;
}
}
Your task is "display the report in PDF or HTML using Strategy Design Pattern", so strategy will be applied here.
Before display Report you should have all computed data (keep the work as was done) and after just pass data and choose appropriate report type.
public interface IReport
{
public void printReport(String data);
}
public class ReportHTML implements IReport
{
#Override
public void printReport(String data) {
System.out.println("Html Report with data="+data);
}
}
public class ReportPDF implements IReport{
#Override
public void printReport(String data) {
System.out.println("PDF Report with data="+data);
}
}
public class Test {
public static void main(String[] args)
{
//do whatever computation concerning business logic
//after for print pass computed data and chose report type as needed
IReport ir = new ReportHTML();
ir.printReport("[Customers, Movie, Rental]");
ir = new ReportPDF();
ir.printReport("[Customers, Movie, Rental]");
}
}
Output:
Html Report with data=[Customers, Movie, Rental]
PDF Report with data=[Customers, Movie, Rental]
HTML and PDF are display formats. A strategy is just a pluggable algorithm, usually defined by an interface. Since the task is to display the report and the pluggable part is how to display it (the algorithm), you need a display strategy. As for names, many people would call the interface ReportDisplayStrategy and that’s fine, but often I think the design pattern name is just pollution, so I’d consider something more like ReportRenderer. If the output is always a file (there’s a lot more you could do here), the interface might look like:
interface ReportRenderer
{
File render(Report report)
}
The rest is matter of making your report object and writing the renderer implementations for PDF and HTML.

Why does this not print the String inside the object?

This program is used for a flash card application. My constructor is using a linked list, but the problem is that when I use a method that list the cards inside a specific box it is not printing the desired result. The system should print "Ryan Hardin". Instead it is printing "Box$NoteCard#68e86f41". Can someone explain why this is happening and what I can do to fix this? I have also attached both my box and note card classes.
import java.util.LinkedList;
import java.util.ListIterator;
public class Box {
public LinkedList<NoteCard> data;
public Box() {
this.data = new LinkedList<NoteCard>();
}
public Box addCard(NoteCard a) {
Box one = this;
one.data.add(a);
return one;
}
public static void listBox(Box a, int index){
ListIterator itr = a.data.listIterator();
while (itr.hasNext()) {
System.out.println(itr.next());
}
}
public static void main(String[] args) {
NoteCard test = new NoteCard("Ryan", "Hardin");
Box box1 = new Box();
box1.addCard(test);
listBox(box1,0);
}
}
This is my NoteCard Class
public class NoteCard {
public static String challenge;
public static String response;
public NoteCard(String front, String back) {
double a = Math.random();
if (a > 0.5) {
challenge = front;
} else
challenge = back;
if (a < 0.5) {
response = front;
} else
response = back;
}
public static String getChallenge(NoteCard a) {
String chal = a.challenge;
return chal;
}
public static String getResponse(NoteCard a) {
String resp = response;
return resp;
}
public static void main(String[] args) {
NoteCard test = new NoteCard("Ryan", "Hardin");
System.out.println("The challenge: " + getChallenge(test));
System.out.println("The response: " + getResponse(test));
}
}
Try to override the method toString() in your class NoteCard.
#Override
public String toString()
{
//Format your NoteCard class as an String
return noteCardAsString;
}
In First place you are making too much use of static keyword. I am not sure whether you need that. Anyways create two instance variable front and back and assign value to it in constructor of NoteCard class, Also implement toString method
public class NoteCard {
public static String challenge;
public static String response;
public String front;
public String back;
public NoteCard(String front, String back) {
//your code
this.front = front;
this.back = back;
}
#Override
public String toString()
{
//return "The challenge:" + challenge + " " + "The response: " + response;
return "The Front:" + front + " " + "The Back: " + back;
}
Note: Since the instance method toString() is implicitly inherited
from Object, declaring a method toString() as static in a sub type
causes a compile-time error SO DON'T MAKE THIS METHOD STATIC

How to print out the contents of a HashMap in a certain format?

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;
}
}

java Error Message: Missing Method Body Or Declare Abstract, how to fix this?

hello I get the error message: Missing Method Body Or Declare Abstract, how to fix this, what does this mean?
my code:
public class Mobile
{
// type of phone
private String phonetype;
// size of screen in inches
private int screensize;
// memory card capacity
private int memorycardcapacity;
// name of present service provider
private String mobileServiceProvider;
// type of contract with service provider
private int mobileTypeOfContract;
// camera resolution in megapixels
private int cameraresolution;
// the percentage of charge left on the phone
private int chargeUp;
// wether the phone has GPS or not
private int switchedOnFor;
// to simulate using phone for a period of time
private int charge;
// checks the phones remaining charge
private String provider;
// simulates changing the provider
private String GPS;
// instance variables - replace the example below with your own
private int cost;
// declares cost of the item
// The constructor method
public Mobile(String mobilephonetype, int mobilescreensize,
int mobilememorycardcapacity, String mobileServiceProvider, int mobileTypeOfContract, int mobilecameraresolution, String mobileGPS, int chargeUp,int switchedOnFor, String changeProvider,int getBalance, int cost,int price) {
// initialise the class attributes from the one given as parameters in your constructor.
}
/**
* Other constructor
*/
public Mobile (int cost){
price = 1000;
// initialise cost(?) attribute that actually doesn't seem to exist?
}
/**
*returns a field price.
*/
public int getcost()
{
return balance;
}
/**
*return the amount of change due for orders of mobiles.
*/
public int getBalance()
{
return balance;
}
/**
* Receive an amount of money from a customer.
*/
public void cost (int price)
{
balance = balance + amount;
}
//this.serviceprovider = newserviceprovider;
//this.typeofcontract = 12;
//this.checkcharge = checkcharge;
//this.changeProvider = giffgaff;
//Mobile samsungPhone = new Mobile(
// "Samsung" // String mobilephonetype
//, 1024 // intmobilescreensize
//, 2 // intmobilememorycardcapacity
//, 8 // intmobilecameraresolution
//, "GPS" //String mobileGPS
//, "verizon" // String newserviceprovider
//, "100" // intchargeUp
//, "25" // intswitchedOnFor
//, "25" // intcheckCharge
//, "giffgaff"// String changeProvider
//);
//typeofcontract = 12;
//checkcharge = checkcharge;
//Mutator for newserviceprovider
public void setmobileServiceProvider(String newmobileServiceProvider)
{
mobileServiceProvider = newmobileServiceProvider;
}
//Mutator for contracttype
public void setmobileTypeOfContract(int newmobileTypeOfContract)
{
mobileTypeOfContract = newmobileTypeOfContract;
}
//Mutator for chargeUp
public void setchargeUp(int chargeUp)
{
this.chargeUp = chargeUp;
}
//Mutator to simulate using phone for a period of time
public void switchedOnFor(int switchedOnFor)
{
this.switchedOnFor = switchedOnFor;
}
//Accessor for type of phone
public String getType()
{
return phonetype;
}
//Accessor for provider
public String getprovider()
{
return mobileServiceProvider;
}
//Accessor for contract type
public int getContractType()
{
return mobileTypeOfContract;
}
//Accessor for charge
public int getCharge()
{
return chargeUp;
}
//Accessor which checks the phones remaining charge
public int checkCharge()
{
return checkCharge;
}
// simulates changing the provider
public void changeProvider()
{
provider = changeProvider;
}
//returns the amount of change due for orders of mobiles.
public int Balance()
{
return balance;
}
// A method to display the state of the object to the screen
public void displayMobileDetails() {
System.out.println("phonetype: " + phonetype);
System.out.println("screensize: " + screensize);
System.out.println("memorycardcapacity: " + memorycardcapacity);
System.out.println("cameraresolution: " + cameraresolution);
System.out.println("GPS: " + GPS);
System.out.println("mobileServiceProvider: " + mobileServiceProvider);
System.out.println("mobileTypeOfContract: " + mobileTypeOfContract );
}
/**
* The mymobile class implements an application that
* simply displays "new Mobile!" to the standard output.
*/
public class mymobile {
public void main(String[] args) {
System.out.println("new Mobile!"); //Display the string.
}
}
public static void buildPhones(){
Mobile Samsung = new Mobile("Samsung",3,4,"verizon",8,12,"GPS",100,25,"giffgaff");
Mobile Blackberry = new Mobile("Samsung",3,4,"verizon",8,12,"GPS",100,25,"giffgaff");
}
public static void main(String[] args) {
buildPhones();
}
}
any answers or replies and help would be greatly appreciated as I cant get it to compile like it did before with no syntax errors.
Check constructor declared on line 42. It doesn't have a body.
public Mobile (int cost); {
price = 1000;
// initialise cost(?) attribute that actually doesn't seem to exist?
}
Additionally, price and a number of other fields are not declared anywhere.
remove ; from
public Mobile (int cost); {
public Mobile (int cost); {
price = 1000;
// initialise cost(?) attribute that actually doesn't seem to exist?
}
Here, you left a semicolon, delete it.
public Mobile (int cost){
price = 1000;
// initialise cost(?) attribute that actually doesn't seem to exist?
}

An Arraylist of Arrays or os there a better way?

So thanks to the wonderful people here i've managed to get something semi workable, still have a couple bugs but maybe you guys can help me figure it out. So far none of the solution provided were a exact match (which is why i havent up voted them) but they did help me look at things in a new way and get things moving forward. So here is the current problem.
First the code then the explination
RaceButtons[RaceCounter] = new JToggleButton();
RaceButtons[RaceCounter].setIcon(RCiconSM);
RaceButtons[RaceCounter].setBorder(BorderFactory.createEmptyBorder());
RaceButtons[RaceCounter].setContentAreaFilled(false);
RaceButtons[RaceCounter].setActionCommand(temp_race.getRaceNameString(RaceCounter));
RaceButtons[RaceCounter].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
Race race = new Race(1, 1, GenderList[PHYSICAL_SEX]);
race.setRaceID(race.getRaceIDFromString(ae.getActionCommand()));
//System.out.println(race.getraceID());
if (RaceButtons[race.getraceID()].isSelected()){
RaceButtons[race.getraceID()].setBorderPainted(true);
RaceButtons[race.getraceID()].setBorder(new LineBorder(Color.blue,2));
MyRaceArray.add(new Race(race.getraceID(), 1, GenderList[PHYSICAL_SEX]));
}else{
RaceButtons[race.getraceID()].setBorderPainted(false);
};
So first i create an array of Toggle buttons and when you click it it draw the border and then getting it's info i can add it to the array for races but this lives me with another problem i cant quite figure the logic off. Namly if there are already selected button it adds another instances to the button, it shouldn't do that it should ignore iexaisting entries but that means i have to check the arry for a matching object of type Race withthe same info right? What's the best way to do that?
And when you deselect it how do i remove that same object.
This is how your code should look like with a Race class:
import java.util.ArrayList;
import java.util.List;
public class Race {
private int raceID;
private double purity;
private int strMod;
private int dexMod;
private int conMod;
private int wisMod;
public int getRaceID() {
return raceID;
}
public void setRaceID(int raceID) {
this.raceID = raceID;
}
public double getPurity() {
return purity;
}
public void setPurity(double d) {
this.purity = d;
}
public int getStrMod() {
return strMod;
}
public void setStrMod(int strMod) {
this.strMod = strMod;
}
public int getDexMod() {
return dexMod;
}
public void setDexMod(int dexMod) {
this.dexMod = dexMod;
}
public int getConMod() {
return conMod;
}
public void setConMod(int conMod) {
this.conMod = conMod;
}
public int getWisMod() {
return wisMod;
}
public void setWisMod(int wisMod) {
this.wisMod = wisMod;
}
#Override
public String toString() {
return "Race [raceID=" + raceID + ", purity=" + purity + ", strMod="
+ strMod + ", dexMod=" + dexMod + ", conMod=" + conMod
+ ", wisMod=" + wisMod + "]";
}
public static void main(String args[]) {
//create a list of race objects
List<Race> raceCollection = new ArrayList<Race>();
//create a race object
Race race = new Race();
race.setRaceID(1);
race.setPurity(0.75);
race.setStrMod(5);
race.setDexMod(7);
race.setConMod(-2);
race.setWisMod(3);
//add race object to collection
raceCollection.add(race);
//You can create and add multiple objects of race to the collection
//Iterate your list and print the objects
for(Race raceObj:raceCollection) {
System.out.println(raceObj);
}
}
}
You will be able to make it work using an ArrayList of arrays, but that possibly isn't the best way in the long run. It can be very fiddly and error-prone to deal with - what happens when you insert a new race or attribute, but forget to to change the index somewhere?
Arrays and ArrayLists are usually best reserved for situations where you actually have a sequence / list (often with a meaningful sequence order).
In your case I'd be more inclined to adopt a prototype model. Typically in Java you would represent each race with a HashMap (or a data structure containing a HashMap), there the map represents the relationship between the "Attribute ID" and the "Default Value".
Creating a new elf is then just a case of initialising the elf's attributes using the default values from his race (or a average of different races, if you want...)
Some people may suggest making an OOP class with lots of named fields. This can also work, but IMHO a prototype model is better - it gives you much more flexibility in the long run. You often want to process large groups of attributes in the some way, and doing this is pretty messy if you have to refer to each of the attribute fields individually.
import java.util.ArrayList;
import java.util.List;
public class Race
{
private final int raceID;
private final double purity;
private final int strMod;
private final int dexMod;
private final int conMod;
private final int wisMod;
public Race (int raceID, double purity, int strMod, int dexMod, int conMod, int wisMod)
{
this.raceID = raceID;
this.purity = purity;
this.strMod = strMod;
this.dexMod = dexMod;
this.conMod = conMod;
this.wisMod = wisMod;
}
public int getRaceID ()
{
return raceID;
}
public double getPurity ()
{
return purity;
}
public int getStrMod ()
{
return strMod;
}
public int getDexMod ()
{
return dexMod;
}
public int getConMod ()
{
return conMod;
}
public int getWisMod ()
{
return wisMod;
}
#Override public String toString ()
{
return "RaceID:" + raceID
+ " purity:" + purity
+ " strMod:" + strMod
+ " dexMod:" + dexMod
+ " conMod:" + conMod
+ " wisMod:" + wisMod;
}
#override public int hashCode ()
{
return raceID;
}
#override public boolean equals (Race r)
{
return (r != null && this.raceID == r.getRaceID());
}
#override public Object clone ()
{
return new Race(this.raceID,this.purity,this.strMod,this.dexMod,this.conMod,this.wisMod);
}
public static void main(String args[])
{
// simple test
ArrayList<Race> races = new ArrayList<Race>();
Race a = new Race(0,0.5,1,2,3,4);
Race b = new Race(1,0.75,2,3,4,5);
Race c = new Race(2,0.25,-1,-2,-3,-4);
races.add(a);
races.add(b);
races.add(c);
for(Race race : races)
{
// System.out.println(race.toString());
System.out.println(race);
}
}
}
Then we have the visual model, which can be handled like this:
class RacePanel implements ActionListener
{
private Map<Integer,JToggleButton> r;
private Map<Integer,Race> f;
public RacePanel()
{
r = new TreeMap<Integer,JToggleButton>();
f = new TreeMap<Integer,Race>();
}
public JToggleButton add (Race a)
{
JToggleButton button = new JToggleButton();
button.setIcon(RCiconSM);
button.setBorder(BorderFactory.createEmptyBorder());
button.setContentAreaFilled(false);
button.setActionCommand(a.getRaceID());
button.addActionListener(this);
r.put(a.getRaceID, button);
f.put(a.getRaceID, a);
}
public void remove (int raceID)
{
r.remove(a.getRaceID);
f.remove(a.getRaceID);
}
// When a button is clicked
public void actionPerformed(ActionEvent e)
{
// related race
Race a = f.get(e.getActionCommand());
// clicked button
JToggleButton b = r.get(e.getActionCommand());
// ..
}
public ArrayList<JToggleButton> getButtonList ()
{
return new ArrayList<Value>(r.values());
}
public ArrayList<Race> getRaceList ()
{
return new ArrayList<Value>(f.values());
}
public Race getRace (int raceID)
{
return f.get(raceID);
}
public JToggleButton getButton (int raceID)
{
return r.get(raceID);
}
// ..
}

Categories

Resources