diff --git a/src/main/java/org/apache/commons/collections4/multimap/AbstractMultiValuedMap.java b/src/main/java/org/apache/commons/collections4/multimap/AbstractMultiValuedMap.java index 76c847d121..0577e65434 100644 --- a/src/main/java/org/apache/commons/collections4/multimap/AbstractMultiValuedMap.java +++ b/src/main/java/org/apache/commons/collections4/multimap/AbstractMultiValuedMap.java @@ -19,7 +19,6 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; -import java.lang.reflect.Array; import java.util.AbstractCollection; import java.util.ArrayList; import java.util.Collection; @@ -39,7 +38,8 @@ import org.apache.commons.collections4.iterators.LazyIteratorChain; import org.apache.commons.collections4.iterators.TransformIterator; import org.apache.commons.collections4.keyvalue.AbstractMapEntry; -import org.apache.commons.collections4.set.UnmodifiableSet; +import org.apache.commons.collections4.multiset.AbstractMultiSet; +import org.apache.commons.collections4.multiset.UnmodifiableMultiSet; /** * Abstract implementation of the {@link MultiValuedMap} interface to simplify @@ -59,7 +59,7 @@ public abstract class AbstractMultiValuedMap implements MultiValuedMap keysMultiSetView; /** The map used to store the data */ private transient Map> map; @@ -308,8 +308,10 @@ public boolean putAll(final MultiValuedMap map) { */ @Override public MultiSet keys() { - return keysMultiSetView != null ? keysMultiSetView - : (keysMultiSetView = new KeysMultiSet()); + if (keysMultiSetView == null) { + keysMultiSetView = UnmodifiableMultiSet.unmodifiableMultiSet(new KeysMultiSet()); + } + return keysMultiSetView; } @Override @@ -526,17 +528,7 @@ public String toString() { /** * Inner class that provides a MultiSet keys view. */ - private class KeysMultiSet implements MultiSet { - - @Override - public boolean addAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public void clear() { - throw new UnsupportedOperationException(); - } + private class KeysMultiSet extends AbstractMultiSet { @Override public boolean contains(Object o) { @@ -549,45 +541,13 @@ public boolean isEmpty() { } @Override - public Object[] toArray() { - final Object[] result = new Object[size()]; - int i = 0; - final Iterator it = getMap().keySet().iterator(); - while (it.hasNext()) { - final K current = it.next(); - for (int index = getCount(current); index > 0; index--) { - result[i++] = current; - } - } - return result; + public int size() { + return AbstractMultiValuedMap.this.size(); } @Override - public T[] toArray(T[] array) { - final int size = size(); - if (array.length < size) { - @SuppressWarnings("unchecked") - // safe as both are of type T - final T[] unchecked = (T[]) Array.newInstance(array.getClass().getComponentType(), size); - array = unchecked; - } - - int i = 0; - final Iterator it = getMap().keySet().iterator(); - while (it.hasNext()) { - final K current = it.next(); - for (int index = getCount(current); index > 0; index--) { - // unsafe, will throw ArrayStoreException if types are not - // compatible, see javadoc - @SuppressWarnings("unchecked") - final T unchecked = (T) current; - array[i++] = unchecked; - } - } - while (i < array.length) { - array[i++] = null; - } - return array; + protected int uniqueElements() { + return getMap().size(); } @Override @@ -601,127 +561,28 @@ public int getCount(Object object) { } @Override - public int setCount(K object, int count) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean add(K object) { - throw new UnsupportedOperationException(); - } - - @Override - public int add(K object, int nCopies) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean remove(Object object) { - throw new UnsupportedOperationException(); - } - - @Override - public int remove(Object object, int nCopies) { - throw new UnsupportedOperationException(); - } - - @Override - public Set uniqueSet() { - return UnmodifiableSet.unmodifiableSet(keySet()); - } - - @Override - public Set> entrySet() { - // TODO: implement - throw new UnsupportedOperationException(); - } - - @Override - public int size() { - return AbstractMultiValuedMap.this.size(); - } - - @Override - public boolean containsAll(Collection coll) { - final Iterator e = coll.iterator(); - while (e.hasNext()) { - if(!contains(e.next())) { - return false; - } - } - return true; + protected Iterator> createEntrySetIterator() { + final MapEntryTransformer transformer = new MapEntryTransformer(); + return IteratorUtils.transformedIterator(map.entrySet().iterator(), transformer); } - @Override - public boolean removeAll(Collection coll) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean retainAll(Collection coll) { - throw new UnsupportedOperationException(); - } - - @Override - public Iterator iterator() { - return new LazyIteratorChain() { - - final Iterator keyIterator = getMap().keySet().iterator(); - - @Override - protected Iterator nextIterator(int count) { - if (!keyIterator.hasNext()) { - return null; + private final class MapEntryTransformer + implements Transformer>, MultiSet.Entry> { + @Override + public MultiSet.Entry transform(final Map.Entry> mapEntry) { + return new AbstractMultiSet.AbstractEntry() { + @Override + public K getElement() { + return mapEntry.getKey(); } - final K key = keyIterator.next(); - final Iterator colIterator = getMap().get(key).iterator(); - Iterator nextIt = new Iterator() { - - @Override - public boolean hasNext() { - return colIterator.hasNext(); - } - - @Override - public K next() { - colIterator.next();// Increment the iterator - // The earlier statement would throw - // NoSuchElementException anyway in case it ends - return key; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - return nextIt; - } - }; - } - @Override - public String toString() { - if (size() == 0) { - return "[]"; - } - final StringBuilder buf = new StringBuilder(); - buf.append('['); - final Iterator it = KeysMultiSet.this.uniqueSet().iterator(); - while (it.hasNext()) { - final Object current = it.next(); - final int count = getCount(current); - buf.append(current); - buf.append(':'); - buf.append(count); - if (it.hasNext()) { - buf.append(", "); - } + @Override + public int getCount() { + return mapEntry.getValue().size(); + } + }; } - buf.append(']'); - return buf.toString(); } - } /**