Collections Data Structure Java

//package com.ryanm.util;
import java.util.NoSuchElementException;
/**
 * Call it an unordered list or a multiset, this collection is defined by
 * oxymorons. Find the original  * 2009/08/bag-unordered-list-fast-remove.html>over here
 * 
 * @author Riven
 * @param 
 */
public class Bag {
  private T[] data;
  private int size;
  /***/
  public Bag() {
    this(4);
  }
  /**
   * @param space
   *            initial size of bag
   */
  @SuppressWarnings("unchecked")
  public Bag(int space) {
    this.data = (T[]) new Object[space];
  }
  /**
   * Add an element
   * 
   * @param t
   */
  public void put(T t) {
    data = ensure(data, size + 1, 1.75f);
    data[size++] = t;
  }
  /**
   * Adds a lot of elements
   * 
   * @param bag
   */
  public void putAll(Bag bag) {
    if (bag.size == 0) {
      return;
    }
    data = ensure(data, this.size + bag.size, 1.75f);
    System.arraycopy(bag.data, 0, this.data, this.size, bag.size);
    this.size += bag.size;
  }
  /**
   * Retrieves an element
   * 
   * @param index
   * @return the indexed element
   */
  public T get(int index) {
    if (index >= size) {
      throw new ArrayIndexOutOfBoundsException();
    }
    return data[index];
  }
  /**
   * Retrieves and removes an element
   * 
   * @param index
   * @return The indexed element
   */
  public T take(int index) {
    if (index >= size) {
      throw new ArrayIndexOutOfBoundsException();
    }
    T took = data[index];
    data[index] = data[--size];
    data[size] = null;
    return took;
  }
  /**
   * Attempts to remove an element
   * 
   * @param t
   *            The element to remove
   * @return t
   * @throws NoSuchElementException
   *             if the element was not found
   */
  public T take(T t) {
    int i = this.indexOf(t);
    if (i == -1) {
      throw new NoSuchElementException();
    }
    return this.take(i);
  }
  /**
   * Tests if an element is present
   * 
   * @param t
   * @return true if t is present, false otherwise
   */
  public boolean contains(T t) {
    return this.indexOf(t) != -1;
  }
  /**
   * Finds the index of an element
   * 
   * @param t
   * @return the index of t, or -1 if not found
   */
  public int indexOf(T t) {
    for (int i = 0; i < size; i++) {
      if (data[i] == t) {
        return i;
      }
    }
    return -1;
  }
  /**
   * Tries to shrink the internal array. If your {@link Bag} holds a lot of
   * elements temporarily and you're concerned with memory usage, it might be
   * worthwhile to call this after a sequence of {@link #take(int)} calls
   */
  @SuppressWarnings("unchecked")
  public void shrink() {
    if (this.data.length > 8) {
      int factor = 4;
      if (this.size < this.data.length / factor) {
        int newSize = Math.max(4, this.size);
        T[] newData = (T[]) new Object[newSize];
        System.arraycopy(this.data, 0, newData, 0, this.size);
        this.data = newData;
      }
    }
  }
  /**
   * Removes all elements
   */
  public void clear() {
    for (int i = 0; i < size; i++) {
      data[i] = null;
    }
    this.size = 0;
  }
  /**
   * The maximum number of elements allowed before the internal array will be
   * grown
   * 
   * @return The size of the internal array
   */
  public int capacity() {
    return this.data.length;
  }
  /**
   * @return The number of held elements
   */
  public int size() {
    return size;
  }
  @SuppressWarnings("unchecked")
  private static final  T[] ensure(T[] src, int minCapacity, float factor) {
    if (src.length >= minCapacity) {
      return src;
    }
    int newCapacity = src.length + 1;
    do {
      newCapacity *= factor;
    } while (newCapacity < minCapacity);
    T[] dst = (T[]) new Object[newCapacity];
    System.arraycopy(src, 0, dst, 0, src.length);
    return dst;
  }
}