package com.lyeeedar.Utils; import java.io.Serializable; import java.util.Arrays; import java.util.Iterator; /** * Collection type a bit like ArrayList but does not preserve the order * of its entities, speedwise it is very good, especially suited for games. */ public class Bag<E> implements Serializable, Iterable<E> { private static final long serialVersionUID = 9141471894142964687L; private Object[] data; public int size = 0; /** * Constructs an empty Bag with an initial capacity of ten. * */ public Bag() { this(10); } /** * Constructs an empty Bag with the specified initial capacity. * * @param capacity the initial capacity of Bag */ public Bag(int capacity) { data = new Object[capacity]; } /** * Removes the element at the specified position in this Bag. * does this by overwriting it with the last element then removing * last element * * @param index the index of element to be removed * @return element that was removed from the Bag */ @SuppressWarnings("unchecked") public E remove(int index) { E o = (E) data[index]; // make copy of element to remove so it can be returned data[index] = data[--size]; // overwrite item to remove with last element data[size] = null; // null last element, so gc can do its work return o; } /** * Removes the first occurrence of the specified element from this Bag, * if it is present. If the Bag does not contain the element, it is * unchanged. does this by overwriting it was last element then removing * last element * * @param o element to be removed from this list, if present * @return <tt>true</tt> if this list contained the specified element */ public boolean remove(E o) { for (int i = 0; i < size; i++) { if (o == data[i]) { data[i] = data[--size]; // overwrite item to remove with last element data[size] = null; // null last element, so gc can do its work return true; } } return false; } /** * Removes from this Bag all of its elements that are contained in the * specified Bag. * * @param bag Bag containing elements to be removed from this Bag * @return {@code true} if this Bag changed as a result of the call */ public boolean removeAll(Bag<E> bag) { boolean modified = false; for (int i = 0; i < bag.size; i++) { Object o1 = bag.get(i); for (int j = 0; j < size; j++) { Object o2 = data[j]; if (o1 == o2) { remove(j); j--; modified = true; break; } } } return modified; } /** * Returns the element at the specified position in Bag. * * @param index index of the element to return * @return the element at the specified position in bag */ @SuppressWarnings("unchecked") public E get(int index) { return (E) data[index]; } /** * Returns true if this list contains no elements. * * @return true if this list contains no elements */ public boolean isEmpty() { return size == 0; } /** * Adds the specified element to the end of this bag. * if needed also increases the capacity of the bag. * * @param o element to be added to this list */ public void add(E o) { // if size greater than data capacity increase capacity if(size == data.length) { grow(); } data[size++] = o; } private void grow() { Object[] oldData = data; int newCapacity = (oldData.length * 3) / 2 + 1; data = new Object[newCapacity]; System.arraycopy(oldData, 0, data, 0, oldData.length); } /** * Removes all of the elements from this bag. The bag will * be empty after this call returns. */ public void clear() { // null all elements so gc can clean up for (int i = 0; i < size; i++) { data[i] = null; } size = 0; } @Override public Iterator<E> iterator() { return new BagIterator(0, size); } class BagIterator implements Iterator<E> { int pos = 0; int size = 0; public BagIterator(){} public BagIterator(int pos, int size) { this.pos = pos; this.size = size; } @Override public boolean hasNext() { return (pos < size); } @SuppressWarnings("unchecked") @Override public E next() { return (E) data[pos++]; } @Override public void remove() { Bag.this.remove(--pos); size--; } } /** * Save the state of the <tt>ArrayList</tt> instance to a stream (that * is, serialize it). * * @serialData The length of the array backing the <tt>ArrayList</tt> * instance is emitted (int), followed by all of its elements * (each an <tt>Object</tt>) in the proper order. */ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ // Write out element count, and any hidden stuff s.defaultWriteObject(); // Write out array length s.writeInt(data.length); // Write out all elements in the proper order. for (int i=0; i<size; i++) s.writeObject(data[i]); } /** * Reconstitute the <tt>ArrayList</tt> instance from a stream (that is, * deserialize it). */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in size, and any hidden stuff s.defaultReadObject(); // Read in array length and allocate array int arrayLength = s.readInt(); Object[] a = data = new Object[arrayLength]; // Read in all elements in the proper order. for (int i=0; i<size; i++) a[i] = s.readObject(); } public void sort() { Arrays.sort(data); } }