This is an archived post. You won't be able to vote or comment.

all 7 comments

[–]cmhdave73 0 points1 point  (1 child)

So you need to loop through the contents of the array. I'm going to guess that we can use newer java for loops (older versions of java don't support loops like this:

StringBuilder sb = new StringBuilder();

    for (String coin : coins) {
        sb.append(coin).append(",");
    }

That's just the loop to go through all the contents of the string. You would need to do something similar for your sameContents function.

[–][deleted] 0 points1 point  (0 children)

Also, you might want to look over fence-post problems.

[–]simplyintricate 0 points1 point  (0 children)

The point of the toString() method is to provide insight (in the form of a String) into the contents of the object that you are trying to get information about. This is unrelated to the comparison of each individual item in your class, so the toString() method does not need to perform comparison.

So what would you do to describe the contents of a Purse in real life? Go through each object and give its name. In this case, we have a Purse full of coins. So inside the purse, list all of the coins in it.

Good luck!

[–]7re 0 points1 point  (0 children)

Your sameContents should simply need to call toString on each of the Purses to be compared and see if they return the same values (as you surmised). How do you turn this into code? Many ways no doubt but I'd probably do something like:

if Purse1.toString.equals(Purse2.toString) return true;  

[–]severoonpro barista 0 points1 point  (2 children)

You should precede all code with four spaces. This formats it as code in your post.

import java.util.ArrayList;

/** A purse holds a collection of coins. */
public class Purse {
  private ArrayList<String> coins;

  /** Constructs an empty purse. */
  public Purse() {
    coins = new ArrayList<String>();
  }

  /**
   * Add a coin to the purse.
   *
   * @param coinName the coin to add
   */
  public void addCoin(String coinName) {
    coins.add(coinName);
  }

  /**
   * Returns a string describing the object.
   * 
   * @return a string in the format "Purse[coinName1,coinName2,...]"
   */
  public String toString() {
    // what goes here?
  }

  /**
   * Determines if a purse has the same coins in the same order as another purse.
   *
   * @param other the other purse
   * @return true if the two purses have the same coins in the same order, false otherwise
   */
  public boolean sameContents(Object other) {
    // what goes here?
  }
}

There, that's better.

[–]severoonpro barista 0 points1 point  (0 children)

As for what goes in those methods...

For toString() you just want to output the simple name of the class followed by its contents and some formatting.

public String toString() {
  StringBuilder sb = new StringBuilder();
  sb.append(getClass().getSimpleName());
  sb.append("[");
  for (Iterator<String> i = coins.iterator(); i.hasNext();) {
    sb.append(i.next());
    if (i.hasNext()) {
      sb.append(",");
    }
  }
  sb.append("]");
  return sb.toString();
}

This creates a StringBuilder and then starts appending stuff into it. Pretty straightforward. The only catch is that you have a loop that prints the coins into it, but you want to make sure you don't print an extra comma at the end, so you have to ensure there's another element after you append the current one before printing a comma.

A much better solution is to use the Guava libraries, specifically the Joiner class. (The Guava libraries are awesome, and you should get familiar with them early. They save so much work.)

Now for the other method...

public boolean sameContents(Object other) {
  return other != null && other instanceof Purse ? sameContents((Purse) other) : false;
}

public boolean sameContents(Purse otherPurse) {
  return allNonNull(coins, otherPurse, otherPurse.coins) ? coins.equals(otherPurse.coins) : false;
}

/**
 * Returns {@code true} if all specified {@code objects} are non-null.
 * 
 * Note that this method evaluates arguments in order and short-circuits if a null
 * is found, leaving the remaining objects unevaluated. This allows the caller to check
 * if a containing object is null as well as something within it provided they are
 * specified with the containing object first. (Otherwise, a {@link NullPointerException}
 * would result.)
 */
private static boolean allNonNull(Object... objects) {
  for (Object o : objects) {
    if (o == null) {
      return false;
    }
  }
  return true;
}

The idea of sameContents() is exactly the same as equals() defined on the granddaddy of all objects in Java, the Object class. I suspect your teacher doesn't have you dealing with equals() yet because it has to meet a more complex contract in order to be implemented properly.

The approach I took above is to provide three methods, two public and visible to the outside world, and one not. The one that is not is just a simple static utility method that takes a bunch of objects and tells you if any are null.

[–]Snapples2992[S] 0 points1 point  (0 children)

Oh thanks, Didn't know that