/******************************************************************************* * Copyright (c) 2005, 2008 Oracle. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0, which accompanies this distribution * and is available at http://www.eclipse.org/legal/epl-v10.html. * * Contributors: * Oracle - initial API and implementation ******************************************************************************/ package org.eclipse.jpt.utility.internal; import java.io.Serializable; import java.util.AbstractCollection; import java.util.Iterator; import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; /** * A collection that allows duplicate elements. *

* The Bag interface places additional stipulations, * beyond those inherited from the java.util.Collection interface, * on the contracts of the equals and hashCode methods. * * @see HashBag */ public interface Bag extends java.util.Collection { /** * Compares the specified object with this bag for equality. Returns * true if the specified object is also a bag, the two bags * have the same size, and every member of the specified bag is * contained in this bag with the same number of occurrences (or equivalently, * every member of this bag is contained in the specified bag with the same * number of occurrences). This definition ensures that the * equals method works properly across different implementations of the * bag interface. */ boolean equals(Object o); /** * Returns the hash code value for this bag. The hash code of a bag is * defined to be the sum of the hash codes of the elements in the bag, * where the hashcode of a null element is defined to be zero. * This ensures that b1.equals(b2) implies that * b1.hashCode() == b2.hashCode() for any two bags * b1 and b2, as required by the general * contract of the Object.hashCode method. */ int hashCode(); /** * Return the number of times the specified object occurs in the bag. */ int count(Object o); /** * Add the specified object the specified number of times to the bag. */ boolean add(E o, int count); /** * Remove the specified number of occurrences of the specified object * from the bag. Return whether the bag changed. */ boolean remove(Object o, int count); /** * Return an iterator that returns each item in the bag * once and only once, irrespective of how many times * the item was added to the bag. */ java.util.Iterator uniqueIterator(); /** * Return an iterator that returns an entry for each item in the bag * once and only once, irrespective of how many times * the item was added to the bag. The entry will indicate the item's * count. */ java.util.Iterator> entries(); /** * A bag entry (element-count pair). * The Bag.entries method returns an iterator whose * elements are of this class. The only way to obtain a reference * to a bag entry is from the iterator returned by this method. These * Bag.Entry objects are valid only for the duration * of the iteration; more formally, the behavior of a bag entry is * undefined if the backing bag has been modified after the entry was * returned by the iterator, except through the setCount * operation on the bag entry. */ interface Entry { /** * Return the entry's element. */ E getElement(); /** * Return entry's count; i.e. the number of times the entry's element * occurs in the bag. * @see Bag#count(Object) */ int getCount(); /** * Set the entry's count; i.e. the number of times the entry's element * occurs in the bag. The new count must be a positive number. * Return the previous count of the entry's element. * NB: Use the iterator's remove method to set the * count to zero. */ int setCount(int count); /** * Return whether the entry is equal to the specified object; * i.e. the specified object is a Bag.Entry and its * element and count are the same as the entry's. */ boolean equals(Object obj); /** * Return the entry's hash code. */ int hashCode(); } final class Empty extends AbstractCollection implements Bag, Serializable { @SuppressWarnings("unchecked") public static final Bag INSTANCE = new Empty(); @SuppressWarnings("unchecked") public static Bag instance() { return INSTANCE; } // ensure single instance private Empty() { super(); } @Override public Iterator iterator() { return EmptyIterator.instance(); } @Override public int size() { return 0; } public Iterator uniqueIterator() { return EmptyIterator.instance(); } public int count(Object o) { return 0; } public Iterator> entries() { return EmptyIterator.instance(); } public boolean remove(Object o, int count) { return false; } public boolean add(E o, int count) { throw new UnsupportedOperationException(); } @Override public boolean equals(Object o) { if (o == this) { return true; } if ( ! (o instanceof Bag)) { return false; } return ((Bag) o).size() == 0; } @Override public int hashCode() { return 0; } private static final long serialVersionUID = 1L; private Object readResolve() { return INSTANCE; } } }