package basictype;
/**
 * A bag is just a collection of data. You can add items to it and get its size.
 * You can also get an iterator on its elements.
 * 
 * @author Frederic Boulanger frederic.boulanger@supelec.fr
 *
 * @param <T> the type of elements in the bag
 * 
 * @spec
 * emptyBag : -> Bag
 * add : Bag, Item -> Bag
 * contains : Bag, Item -> Bool
 * size : Bag -> Nat
 * 
 * contains(emptyBag, e) = false
 * contains(add(b, e_1), e_2) = if (e_1 = e_2) then true else contains(b, e_2) endif
 * size(Bag) = 0
 * size(add(b,i)) = succ(size(b))
 * 
 */
public abstract class Bag<T> implements Iterable<T> {
  // operations from the specification (excepted 
  // constants, which will be handled by class constructors)
  public abstract void add(T item);
  public abstract int size();
  // Simple default implementation of contains.
  // Subclasses where a more efficient implementation is possible may override this
  public boolean contains(T item) {
    for (T element : this) {
      if (item.equals(element)) {
        return true;
      }
    }
    return false;
  }
  // operations linked to the Java framework
  @Override
  public String toString() {
    // Use a StringBuffer instead of String concatenation for efficiency
    StringBuffer result = new StringBuffer("[");
    boolean first = true;
    for (T item : this) {
      // prepend a comma ans a space before all items but the first one
      if (first) {
        first = false;
      } else {
        result.append(", ");
      }
      result.append(item.toString());
    }
    result.append("]");
    return result.toString();
  }
}
