-1

I am trying to do some practice Java. Right now I am doing exercises from a textbook for fun and I am stuck on one problem. This particular problem requires me to create a class called "Purse" and then create "Coins" which can be added to a given purse. This part I have been able to do. The last part of the exercise is to print the purse by using a toString method. I will show my classes below.

Purse

package exercisePurse;

import java.util.ArrayList;

public class Purse {

    private ArrayList<Coin> coins;

    public Purse(){

        coins = new ArrayList<Coin>();

    }

    public void addCoin(Coin a){

        coins.add(a);

    }

    public String getCoins(){

        String allCoins = coins.toString();

        return allCoins;

    }

}

Coin

package exercisePurse;

public class Coin 

{

    String coin;
    int value;

    public Coin(String coinName, int coinValue){

        coin = coinName;
        value = coinValue;

    }

}

Tester class

package exercisePurse;

import java.util.ArrayList;

public class CoinTester 

{

    public static void main(String args[]){

        Purse purse1 = new Purse();
        purse1.addCoin(new Coin("Quarter", 2));
        purse1.addCoin(new Coin("Dime", 3));
        purse1.addCoin(new Coin("Nickle", 4));
        purse1.addCoin(new Coin("Penny", 10));

        System.out.println(purse1.getCoins());

    }

}

Results of a run

[exercisePurse.Coin@2a139a55, exercisePurse.Coin@15db9742, exercisePurse.Coin@6d06d69c, exercisePurse.Coin@7852e922]

Specifically I know my problem area is here

public String getCoins(){

        String allCoins = coins.toString();

        return allCoins;

    }

What I want is for the purse to display the coin names and values. So something like this:

purse1[Quarters 2, Dimes 3, Nickles 2, Pennies 5]

Any help is appreciated, sorry if this has been asked before because I know there are posts on using toString I just couldn't figure out how to implement a solution in this case.

EDIT:

I need to specifically follow these instructions to consider the exercise complete:

Implement a class Purse. A purse contains a collection of coins. For simplicity, we
will only store the coin names in an ArrayList<String>. (We will discuss a better representation
in Chapter 8.) Supply a method
void addCoin(String coinName)
Add a method toString to the Purse class that prints the coins in the purse in the
format
Purse[Quarter,Dime,Nickel,Dime]
jesric1029
  • 698
  • 3
  • 10
  • 33

5 Answers5

1

It is printing the reference of the Coin object and not the value. What you have to do is either:

  1. Override the toString() method on the Coin.

    public String getCoins(){
        String allCoins = coins.toString();
        return allCoins;
    }
    
    public class Coin {
        private String coin;
        private int value;
    
        public Coin(String coinName, int coinValue){
            this.coin = coinName;
            this.value = coinValue;
        }
    
        public String toString(){
            return this.coin + " " + String.valueOf(this.value);
        }
    
        /* Getter-Setters */
    }
    
  2. Or iterate the list and prepare the result String:

    public String getCoins() {
        /* Assuming you include `purseName` member in the purse class for storing purse name */
        StringBuilder sb = new StringBuilder(this.purseName + "[");
        for(Coin c : coins) {
            sb.append(c.getCoin() + " " + c.getValue() + ", ");
        }
        return sb.append("]").toString();
    }
    

Tip: You should use the getter-setters for getting and setting the class members.
Alternatively, you can set the visibility to public if you are not using the getter-setters.

ankhzet
  • 2,517
  • 1
  • 24
  • 31
user2004685
  • 9,548
  • 5
  • 37
  • 54
  • May I know why this has been down-voted? – user2004685 Mar 17 '16 at 15:23
  • I did not down vote but I'd like to add that your solution does work but the text describes it like this: "Add a method toString to the Purse class that prints the coins in the purse in the format Purse[Quarter,Dime,Nickel,Dime]" Can you give a solution that meets that format, that is what I'm having trouble with. – jesric1029 Mar 17 '16 at 15:26
  • why change the modifier to `public`? – Haifeng Zhang Mar 17 '16 at 15:27
  • @jesric1029 Please check the updated solution. – user2004685 Mar 17 '16 at 15:30
  • 1
    (not downvoter) don't agree with publicity here (Coin/Purse in the same package), plus using getter/setter is best practice. Also, direct `StringBuilder/Buffer` usage is outdated, afaik, modern compilators can automatically optimize in-loop string concatenations by themself. Also, premature optimization is premature optimization... Suggesting simple `String r = ""; for (Coint c: coins) r += (r.isEmpty() ? "" : ", ") + coin.coin + " " + coin.value; return "[" + r + "]";` or alike as alternative. – ankhzet Mar 17 '16 at 15:35
  • Thanks. It printed in this format "Quarter Dime Nickle Penny " The directions stated it needed to print in the format where the name of the purse is first like this "purse1[quarter dime nickle penny]" if you know how to add this part let me know but I'll still mark as answered. – jesric1029 Mar 17 '16 at 15:36
  • If you overriding `toString()` in `Coin`, then `toString()` in Purse can just contain `sb.append(c.toString())`, but direct `StringBuilder` usage will be completely useless. Either don't override `toString()` in `Coin`, or don't bother with builder... – ankhzet Mar 17 '16 at 15:39
  • 1
    @jesric1029, use my example in comment previous to yours, but 1) add `name` property to `Purse` 2) allow to pass name to purse via purse object constructor 3) change return statement in `Purse.toString()` to `return name + " [" + r + "]";` – ankhzet Mar 17 '16 at 15:42
  • @ankhzet I written this answer in bit of a hurry and was not thinking about the *Most Optimized Code*. Well I agree with some of your points but still I don't prefer doing `r += ...` for Strings are immutable. What is the problem in using a StringBuilder/StringBuffer? – user2004685 Mar 17 '16 at 17:12
  • The problem is quite the same as with reimplementing quicksort - to much redundant code for zero gain. Using `StringBuilder` for simple concatenation is just an overkill. What the point to avoid direct string concatenation and then just write `sb.append(c.getCoin() + " " + c.getValue() + ", ");`? Either don't use concatenation (`sb.append(c.getCoin()).append(" ").append(c.getValue()).append(", ");` as in most java native sources with builder usage), or not use builder at all, and leave possible optimizations to compiller, as builder in such a trivial usecase is a premature optimization. – ankhzet Mar 17 '16 at 18:23
  • `for Strings are immutable` - `String`s - are, function result variable - not. – ankhzet Mar 17 '16 at 18:28
1

As there say:when you call List.toString(),it will print out the element.toString() one by one,but you didn't custom the method for this element:Coin object,so its address is print out.

To make what you want,just implement toString() method for your Coin class,like this:

public class Coin {
    String coin;
    int value;

    public Coin(String coinName, int coinValue){
        coin = coinName;
        value = coinValue;
    }

    public String toString(){
        StringBuffer sb = new StringBuffer();
        sb.append("coinName=");
        sb.append(this.coin);
        sb.append(";");
        sb.append("value=");
        sb.append(this.value);
        return sb.toString();
    }
}
starkshang
  • 8,228
  • 6
  • 41
  • 52
1
public class Coin{
    String coin;
    int value;

    public Coin(String coinName, int coinValue){
        coin = coinName;
        value = coinValue;
    }

    @Override
    public String toString(){
        StringBuilder sb = new StringBuilder();
        sb.append("Coin name:").append(this.coin).append(",")
        .append("Coin value:").append(this.value);

        return sb.toString();
    }
}

When you get your coins from purse, iterate the list and print out all coins information.

ArrayList<Coins> coins = purse1.getCoins();

for(Coin coin: coins){
    System.out.println(coin.toString);
}
Haifeng Zhang
  • 30,077
  • 19
  • 81
  • 125
0

override the toString() method on Coin

public String toString() {
    return coin + "s" + value;
}
David
  • 589
  • 6
  • 21
-1

All "non-primitive" data types come with a to[TYPE]() method for their primitive "equivalent". (toString(), toDouble(), toInteger(), etc.)

With this, it will be "transformed" on the spot to return certain information.

For example, lets say you have this class.

public class Foo{
   private String _foo = "bar";  
   private int foobar = 0;
   public String toString(){
      return _foo;
   }
   public Integer toInteger(){
      return foobar;
   }
}

public class FooBar{
   public static void main(){
      Foo bar;
      System.out.println(bar);
      Integer z = 5 + bar;
      System.out.println(z);
    }

}

A call on main will write

bar
 5

This can be done with any class, and in (nearly) any situation.

Add a to[TYPE]() method and return the data you want/need to return.

Essentially, what you would do for this case would be

public class FOOBAR{
   public static void main(){
   java.util.ArrayList<Foo>baz;
   Foo bar;
   Foo foobar;
   baz.add(bar);
   baz.add(foobar)
      for(Foo f : baz){
         System.out.println(f);

      } 
   }
}

A call on main will output

bar
bar
DarmaniLink
  • 126
  • 10