0

I have been away from Java for awhile and am trying to recall and learn a lot still. I have a current project which is a piggy bank that you add coins to and can get various outputs. I am currently tasked with 5 methods plus a helper method for the constructors. I know what I want to do, but can't think through the code to get it done. I want to use the helper method to get the amounts for the other two constructors, but cannot get my head around it, I can only look through my book so long. Any input is appreciated. The description for each method is as follows:

P.S. The code I do have may not be correct.

publicChangeJar() Default constructor that sets all the instance variables to zero

publicChangeJar(int quarters, int dimes, int nickels, int pennies) A constructor that initializes the instance variables with the provided values converted to quarters, dimes, nickels, and pennies.

public ChangeJar(final double amount) A constructor that initializes the instance variables with the provided value converted to quarters, dimes, nickels, and pennies. For example, if amount was 1.34 then you would have 5 quarters, 1 nickel, 4 pennies

public ChangeJar(final String amount)A constructor that accepts a string as a parameter with the provided value converted to appropriate number of quarters, dimes, nickels, and pennies. For example, if amount was “1.34” then you would have 5 quarters, 1 nickel, 4 pennies.

public ChangeJar(final ChangeJar other)A constructor that initializesthe instance variables of “this” ChangeJar object with the other object.

public class ChangeJar {
private int pennies;
private int nickels;
private int dimes;
private int quarters;

static boolean globalLock = false;

public ChangeJar(){
    this(0,0,0,0);
}

public ChangeJar(int pennies, int nickels, int dimes, int quarters)throws IllegalArgumentException {
if (pennies < 0 || nickels < 0 || dimes < 0 || quarters < 0)
    throw new IllegalArgumentException("You cannot have negative coins in the jar");
else this.pennies = this.pennies + pennies; 
    this.nickels = this.nickels + nickels;
    this.dimes = this.dimes + dimes; 
    this.quarters = this.quarters + quarters;

}

public ChangeJar(double amount){

}
public ChangeJar(final String amount){

}
private double amountHelper(double amount){
    amount = pennies*.01 + nickels*.05 + dimes*.10 + quarters*0.25;
    return amount;
}

public ChangeJar(final ChangeJar other){

}

}

EDIT: My problem here is how to write the helper method to work in both constructors.

FunTK
  • 13
  • 2
  • 5

1 Answers1

1

Constructor ChangeJar(double)

For your constructor with an amount, you want to use the maximum number of quarters, then the maximum number of pennies, and so on.

Let's say I have $2.87.

  • First, I will take 11 quarters. We still have $0.12 left.
  • Then, I will take 1 dime. We still have $0.02 left.
  • Then, I will take 0 nickel. We still have $0.02 left.
  • Then, I will take 2 pennies. We're done.

How to implement that? Let's say the amount is 2.87.

public ChangeJar(double amount) {
    // How many quarters?
    int quarters = (int) (amount / .25); // The division gives 9.48 and we cast the result to int so we get 9
    amount = amount - quarters * .25;
    System.out.println(quarters + " quarters. Remains: " + amount);

    // How many dimes?
    int dimes = (int) (amount / .10);
    amount = amount - dimes * .10;
    System.out.println(dimes + " dimes. Remains: " + amount);

    // How many nickels?
    int nickels = (int) (amount / .05);
    amount = amount - nickels * .05;
    System.out.println(nickels + " nickels. Remains: " + amount);

    // How many pennies?
    int pennies = (int) (amount / .01);
    amount = amount - pennies * .01;
    System.out.println(pennies + " pennies. Remains: " + amount);

    // Prints:
    // 11 quarters. Remains: 0.1200000000000001
    // 1 dimes. Remains: 0.0200000000000001
    // 0 nickels. Remains: 0.0200000000000001
    // 2 pennies. Remains: 1.0061396160665481E-16

    // Now we just set this in our properties:
    this.quarters = quartes;
    this.dimes = dimes;
    this.nickels = nickels;
    this.pennies = pennies;
}

As you can see, the problem is that the remainders are strange values. The constructor works but it's not really cool. Why? Because Java approximates the doubles.

I would suggest to work with ints. For example, you could change your unit from $ to $/100. Our same example with integer values (the input is not 2.87 but 287):

public ChangeJar(int amount) {
    // How many quarters?
    int quarters = amount / 25;
    amount = amount - quarters * 25;
    System.out.println(quarters + " quarters. Remains: " + amount);

    // How many dimes?
    int dimes = amount / 10;
    amount = amount - dimes * 10;
    System.out.println(dimes + " dimes. Remains: " + amount);

    // How many nickels?
    int nickels = amount / 5;
    amount = amount - nickels * 5;
    System.out.println(nickels + " nickels. Remains: " + amount);

    // How many pennies?
    int pennies = amount;
    amount = amount - pennies;
    System.out.println(pennies + " pennies. Remains: " + amount);

    // Prints:
    // 11 quarters. Remains: 12
    // 1 dimes. Remains: 2
    // 0 nickels. Remains: 2
    // 2 pennies. Remains: 0

    // Now we just set this in our properties:
    this.quarters = quartes;
    this.dimes = dimes;
    this.nickels = nickels;
    this.pennies = pennies;
}

That's already better!

But there is a lot of copy/paste in my code...
How could we make it better?

We can see that for each coin, I get the number of coins and then I subtract the value from the amount.

int amount = 287;

int[] values = new int[]{25, 20, 5, 1}; // The values of my coins
int[] results = new int[values.length];

for (int i = 0; i < values.length; i++) {
    int valueOfCoin = values[i];
    int numberOfCoins = amount / valueOfCoin; // Division gives the integer part of the result
    results[i] = numberOfCoins;

    amount = amount % valueOfCoin; // Modulo gives the remainder part of the result
    // Or you could simply write: amount %= valueOfCoin;
}

System.out.println("RESULTS=" + Arrays.toString(results));

// Prints:
// RESULTS=[9, 1, 0, 2]

Constructor ChangeJar(String)

I suppose that the String is an amount so we will just convert the String to a Double and call the other constructor (ChangeJar(double)).

public ChangeJar(String amount) {
    this(Double.valueOf(amount)); // Double.valueOf() will try to convert the String => Double
}

Constructor ChangeJar(ChangeJar)

The idea is just to copy the values of the other ChangeJar:

public ChangeJar(ChangeJar other) {
    this(other.quarters, other.dimes, other.nickels, other.pennies);
}
Community
  • 1
  • 1
Vincent Durmont
  • 813
  • 8
  • 16
  • Thank you. I appreciate the help. There seems to be a problem when I write the ChangeJar(double amount) method. At the end of the method, when you set the properties, Eclipse is saying that the constructor call must be the first statement in the constructor. What should I do about this? Also I am still interested in using the helper method in both amount methods or doesnt it make sense to do so? – FunTK Jan 14 '15 at 20:39
  • That is totally true, I made a mistake. I edited my answer. You can call the constructor if and only if it is the first statement. Is it better now? – Vincent Durmont Jan 14 '15 at 20:43
  • It makes sense to use a helper method if you feel like it, it is not mandatory. I gave you the algorithm that helps you get the results. You'll have to use it to init your object. If the object works without the helper method, it's fine. You will write the helper if you need to call this method again from somewhere else. – Vincent Durmont Jan 14 '15 at 20:52
  • When I move it to the first statement, Eclipse then references the global variables quarter, dimes, nickels, and pennies. Then it reports that I should change the global instance variables to static. – FunTK Jan 14 '15 at 21:06
  • Yes, look at my edit. You should set the values "manually". A full version is here: http://pastebin.com/ne4PNbGm Does it help? As you can see, the helper method `distributeAmount` could stay in the constructor because it is not used anywhere else. – Vincent Durmont Jan 14 '15 at 21:07
  • Ahh yes, now I see. That clears things up. Thanks again. Now I can walk through it step by step. – FunTK Jan 14 '15 at 21:14
  • Ok. Do not hesitate if you need details. If I answered your question, do not forget to "accept" it by clicking the checkmark on the left of the answer. Good luck! – Vincent Durmont Jan 14 '15 at 21:15