public interface Bag extends Collection
{
int getCount(Object object);
boolean add(Object object);
boolean add(Object object, int nCopies);
boolean remove(Object object);
boolean remove(Object object, int nCopies);
Set uniqueSet();
int size();
boolean containsAll(Collection coll);
boolean removeAll(Collection coll);
boolean retainAll(Collection coll);
Iterator iterator();
}
public interface SortedBag extends Bag
{
public Comparator comparator();
public Object first();
public Object last();
}
public abstract class DefaultMapBag implements Bag
{
private Map _map = null;//底層數據存儲區
private int _total = 0; //元素總個數
private int _mods = 0;//修改次數
public DefaultMapBag() {
}
protected DefaultMapBag(Map map) {
setMap(map);
}
public boolean add(Object object) {
return add(object, 1);
}
public boolean add(Object object, int nCopies) {
_mods++;
if (nCopies > 0) {
int count = (nCopies + getCount(object));
_map.put(object, new Integer(count));
_total += nCopies;
return (count == nCopies);
} else {
return false;
}
}
public boolean addAll(Collection coll) {
boolean changed = false;
Iterator i = coll.iterator();
while (i.hasNext()) {
boolean added = add(i.next());
changed = changed || added;
}
return changed;
}
public void clear() {
_mods++;
_map.clear();
_total = 0;
}
public boolean contains(Object object) {
return _map.containsKey(object);
}
public boolean containsAll(Collection coll) {
return containsAll(new HashBag(coll));
}
public boolean containsAll(Bag other) {
boolean result = true;
Iterator i = other.uniqueSet().iterator();
while (i.hasNext()) {
Object current = i.next();
boolean contains = getCount(current) >= other.getCount(current);
result = result && contains;
}
return result;
}
public boolean equals(Object object) {
if (object == this) {
return true;
}
if (object instanceof Bag == false) {
return false;
}
Bag other = (Bag) object;
if (other.size() != size()) {
return false;
}
for (Iterator it = _map.keySet().iterator(); it.hasNext();) {
Object element = it.next();
if (other.getCount(element) != getCount(element)) {
return false;
}
}
return true;
}
public int hashCode() {
return _map.hashCode();
}
public boolean isEmpty() {
return _map.isEmpty();
}
public Iterator iterator() {
return new BagIterator(this, extractList().iterator());
}
static class BagIterator implements Iterator {
private DefaultMapBag _parent = null;
private Iterator _support = null;//原始迭代器
private Object _current = null;//當前元素
private int _mods = 0;
public BagIterator(DefaultMapBag parent, Iterator support) {
_parent = parent;
_support = support;
_current = null;
_mods = parent.modCount();
}
public boolean hasNext() {
return _support.hasNext();
}
public Object next() {
if (_parent.modCount() != _mods) {
throw new ConcurrentModificationException();
}
_current = _support.next();
return _current;
}
public void remove() {
if (_parent.modCount() != _mods) {
throw new ConcurrentModificationException();
}
_support.remove();
_parent.remove(_current, 1);
_mods++;
}
}
public boolean remove(Object object) {
return remove(object, getCount(object));
}
public boolean remove(Object object, int nCopies) {
_mods++;
boolean result = false;
int count = getCount(object);
if (nCopies <= 0) {
result = false;
} else if (count > nCopies) {
_map.put(object, new Integer(count - nCopies));
result = true;
_total -= nCopies;
} else { // count > 0 && count <= i
// need to remove all
result = (_map.remove(object) != null);
_total -= count;
}
return result;
}
public boolean removeAll(Collection coll) {
boolean result = false;
if (coll != null) {
Iterator i = coll.iterator();
while (i.hasNext()) {
boolean changed = remove(i.next(), 1);
result = result || changed;
}
}
return result;
}
public boolean retainAll(Collection coll) {
return retainAll(new HashBag(coll));
}
public boolean retainAll(Bag other) {
boolean result = false;
Bag excess = new HashBag();
Iterator i = uniqueSet().iterator();
while (i.hasNext()) {
Object current = i.next();
int myCount = getCount(current);
int otherCount = other.getCount(current);
if (1 <= otherCount && otherCount <= myCount) {
excess.add(current, myCount - otherCount);
} else {
excess.add(current, myCount);
}
}
if (!excess.isEmpty()) {
result = removeAll(excess);
}
return result;
}
public Object[] toArray() {
return extractList().toArray();
}
public Object[] toArray(Object[] array) {
return extractList().toArray(array);
}
public int getCount(Object object) {
int result = 0;
Integer count = MapUtils.getInteger(_map, object);
if (count != null) {
result = count.intValue();
}
return result;
}
public Set uniqueSet() {
return UnmodifiableSet.decorate(_map.keySet());
}
public int size() {
return _total;
}
protected int calcTotalSize() {
_total = extractList().size();
return _total;
}
protected void setMap(Map map) {
if (map == null || map.isEmpty() == false) {
throw new IllegalArgumentException("The map must be non-null and empty");
}
_map = map;
}
protected Map getMap() {
return _map;
}
private List extractList() {
List result = new ArrayList();
Iterator i = uniqueSet().iterator();
while (i.hasNext()) {
Object current = i.next();
for (int index = getCount(current); index > 0; index--) {
result.add(current);
}
}
return result;
}
private int modCount() {
return _mods;
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("[");
Iterator i = uniqueSet().iterator();
while (i.hasNext()) {
Object current = i.next();
int count = getCount(current);
buf.append(count);
buf.append(":");
buf.append(current);
if (i.hasNext()) {
buf.append(",");
}
}
buf.append("]");
return buf.toString();
}
}
public class HashBag extends DefaultMapBag implements Bag
{
public HashBag() {
super(new HashMap());
}
public HashBag(Collection coll) {
this();
addAll(coll);
}
}
public class TreeBag extends DefaultMapBag implements SortedBag
{
public TreeBag() {
super(new TreeMap());
}
public TreeBag(Comparator comparator) {
super(new TreeMap(comparator));
}
public TreeBag(Collection coll) {
this();
addAll(coll);
}
public Object first() {
return ((SortedMap) getMap()).firstKey();
}
public Object last() {
return ((SortedMap) getMap()).lastKey();
}
public Comparator comparator() {
return ((SortedMap) getMap()).comparator();
}
}
使用decorate模式的Bag工具類
public class BagUtils
{
/**
* An empty unmodifiable bag.
*/
public static final Bag EMPTY_BAG = UnmodifiableBag.decorate(new HashBag());
/**
* An empty unmodifiable sorted bag.
*/
public static final Bag EMPTY_SORTED_BAG = UnmodifiableSortedBag.decorate(new TreeBag());
public BagUtils() {//這裡按常理不應該是public,應該是private才對,作者應該有其他地方要用到吧
}
public static Bag synchronizedBag(Bag bag) {
return SynchronizedBag.decorate(bag);
}
public static Bag unmodifiableBag(Bag bag) {
return UnmodifiableBag.decorate(bag);
}
public static Bag predicatedBag(Bag bag, Predicate predicate) {
return PredicatedBag.decorate(bag, predicate);
}
public static Bag typedBag(Bag bag, Class type) {
return TypedBag.decorate(bag, type);
}
public static Bag transformedBag(Bag bag, Transformer transformer) {
return TransformedBag.decorate(bag, transformer);
}
public static SortedBag synchronizedSortedBag(SortedBag bag) {
return SynchronizedSortedBag.decorate(bag);
}
public static SortedBag unmodifiableSortedBag(SortedBag bag) {
return UnmodifiableSortedBag.decorate(bag);
}
public static SortedBag predicatedSortedBag(SortedBag bag, Predicate predicate) {
return PredicatedSortedBag.decorate(bag, predicate);
}
public static SortedBag typedSortedBag(SortedBag bag, Class type) {
return TypedSortedBag.decorate(bag, type);
}
public static SortedBag transformedSortedBag(SortedBag bag, Transformer transformer) {
return TransformedSortedBag.decorate(bag, transformer);
}
}