mirror of
https://github.com/apache/commons-collections.git
synced 2025-02-17 15:35:00 +00:00
Continue review of multimap package.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/collections/trunk@1685299 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
4f5a854b28
commit
1954a51bb5
@ -43,11 +43,10 @@ public interface ListValuedMap<K, V> extends MultiValuedMap<K, V> {
|
||||
* @param key the key to retrieve
|
||||
* @return the {@code List} of values, implementations should return an
|
||||
* empty {@code List} for no mapping
|
||||
* @throws ClassCastException if the key is of an invalid type
|
||||
* @throws NullPointerException if the key is null and null keys are invalid
|
||||
*/
|
||||
@Override
|
||||
List<V> get(Object key);
|
||||
List<V> get(K key);
|
||||
|
||||
/**
|
||||
* Removes all values associated with the specified key.
|
||||
@ -60,7 +59,6 @@ public interface ListValuedMap<K, V> extends MultiValuedMap<K, V> {
|
||||
* @return the {@code List} of values removed, implementations
|
||||
* typically return an empty, unmodifiable {@code List} for no mapping found
|
||||
* @throws UnsupportedOperationException if the map is unmodifiable
|
||||
* @throws ClassCastException if the key is of an invalid type
|
||||
* @throws NullPointerException if the key is null and null keys are invalid
|
||||
*/
|
||||
@Override
|
||||
|
@ -18,6 +18,7 @@ package org.apache.commons.collections4;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -57,8 +58,8 @@ public class MultiMapUtils {
|
||||
/**
|
||||
* Returns immutable EMPTY_MULTI_VALUED_MAP with generic type safety.
|
||||
*
|
||||
* @param <K> the type of key in the map
|
||||
* @param <V> the type of value in the map
|
||||
* @param <K> the type of key in the map
|
||||
* @param <V> the type of value in the map
|
||||
* @return immutable and empty <code>MultiValuedMap</code>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -72,8 +73,8 @@ public class MultiMapUtils {
|
||||
* Returns an immutable empty <code>MultiValuedMap</code> if the argument is
|
||||
* <code>null</code>, or the argument itself otherwise.
|
||||
*
|
||||
* @param <K> the type of key in the map
|
||||
* @param <V> the type of value in the map
|
||||
* @param <K> the type of key in the map
|
||||
* @param <V> the type of value in the map
|
||||
* @param map the map, may be null
|
||||
* @return an empty {@link MultiValuedMap} if the argument is null
|
||||
*/
|
||||
@ -100,8 +101,8 @@ public class MultiMapUtils {
|
||||
/**
|
||||
* Gets a Collection from <code>MultiValuedMap</code> in a null-safe manner.
|
||||
*
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param map the {@link MultiValuedMap} to use
|
||||
* @param key the key to look up
|
||||
* @return the Collection in the {@link MultiValuedMap}, or null if input map is null
|
||||
@ -110,7 +111,7 @@ public class MultiMapUtils {
|
||||
if (map != null) {
|
||||
return map.get(key);
|
||||
}
|
||||
return null;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// TODO: review the getValuesAsXXX methods - depending on the actual MultiValuedMap type, changes
|
||||
@ -119,8 +120,8 @@ public class MultiMapUtils {
|
||||
/**
|
||||
* Gets a List from <code>MultiValuedMap</code> in a null-safe manner.
|
||||
*
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param map the {@link MultiValuedMap} to use
|
||||
* @param key the key to look up
|
||||
* @return the Collection in the {@link MultiValuedMap} as List, or null if input map is null
|
||||
@ -139,8 +140,8 @@ public class MultiMapUtils {
|
||||
/**
|
||||
* Gets a Set from <code>MultiValuedMap</code> in a null-safe manner.
|
||||
*
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param map the {@link MultiValuedMap} to use
|
||||
* @param key the key to look up
|
||||
* @return the Collection in the {@link MultiValuedMap} as Set, or null if input map is null
|
||||
@ -159,8 +160,8 @@ public class MultiMapUtils {
|
||||
/**
|
||||
* Gets a Bag from <code>MultiValuedMap</code> in a null-safe manner.
|
||||
*
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param map the {@link MultiValuedMap} to use
|
||||
* @param key the key to look up
|
||||
* @return the Collection in the {@link MultiValuedMap} as Bag, or null if input map is null
|
||||
@ -183,8 +184,8 @@ public class MultiMapUtils {
|
||||
* Creates a {@link ListValuedMap} with an {@link java.util.ArrayList ArrayList} as
|
||||
* collection class to store the values mapped to a key.
|
||||
*
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @return a new <code>ListValuedMap</code>
|
||||
*/
|
||||
public static <K, V> ListValuedMap<K, V> newListValuedHashMap() {
|
||||
@ -195,9 +196,9 @@ public class MultiMapUtils {
|
||||
* Creates a {@link ListValuedMap} with a {@link java.util.HashMap HashMap} as its internal
|
||||
* storage which maps the keys to list of type <code>listClass</code>.
|
||||
*
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param <C> the List class type
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param <C> the List class type
|
||||
* @param listClass the class of the list
|
||||
* @return a new {@link ListValuedMap}
|
||||
*/
|
||||
@ -209,8 +210,8 @@ public class MultiMapUtils {
|
||||
* Creates a {@link SetValuedMap} with an {@link java.util.HashSet HashSet} as
|
||||
* collection class to store the values mapped to a key.
|
||||
*
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @return a new {@link SetValuedMap}
|
||||
*/
|
||||
public static <K, V> SetValuedMap<K, V> newSetValuedHashMap() {
|
||||
@ -221,9 +222,9 @@ public class MultiMapUtils {
|
||||
* Creates a {@link SetValuedMap} with a {@link java.util.HashMap HashMap} as its internal
|
||||
* storage which maps the keys to a set of type <code>setClass</code>
|
||||
*
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param <C> the Set class type
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param <C> the Set class type
|
||||
* @param setClass the class of the set
|
||||
* @return a new {@link SetValuedMap}
|
||||
*/
|
||||
@ -238,11 +239,11 @@ public class MultiMapUtils {
|
||||
* Returns an <code>UnmodifiableMultiValuedMap</code> backed by the given
|
||||
* map.
|
||||
*
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param map the {@link MultiValuedMap} to decorate, must not be null
|
||||
* @return an unmodifiable {@link MultiValuedMap} backed by the provided map
|
||||
* @throws IllegalArgumentException if map is null
|
||||
* @throws NullPointerException if map is null
|
||||
*/
|
||||
public static <K, V> MultiValuedMap<K, V> unmodifiableMultiValuedMap(
|
||||
final MultiValuedMap<? extends K, ? extends V> map) {
|
||||
@ -264,13 +265,13 @@ public class MultiMapUtils {
|
||||
* If there are any elements already in the map being decorated, they are
|
||||
* NOT transformed.
|
||||
*
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param map the {@link MultiValuedMap} to transform, must not be null, typically empty
|
||||
* @param keyTransformer the transformer for the map keys, null means no transformation
|
||||
* @param valueTransformer the transformer for the map values, null means no transformation
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param map the {@link MultiValuedMap} to transform, must not be null, typically empty
|
||||
* @param keyTransformer the transformer for the map keys, null means no transformation
|
||||
* @param valueTransformer the transformer for the map values, null means no transformation
|
||||
* @return a transformed <code>MultiValuedMap</code> backed by the given map
|
||||
* @throws IllegalArgumentException if map is null
|
||||
* @throws NullPointerException if map is null
|
||||
*/
|
||||
public static <K, V> MultiValuedMap<K, V> transformedMultiValuedMap(final MultiValuedMap<K, V> map,
|
||||
final Transformer<? super K, ? extends K> keyTransformer,
|
||||
|
@ -73,7 +73,6 @@ public interface MultiValuedMap<K, V> {
|
||||
*
|
||||
* @param key key whose presence in this map is to be tested
|
||||
* @return true if this map contains a mapping for the specified key
|
||||
* @throws ClassCastException if the key is of an inappropriate type for this map (optional)
|
||||
* @throws NullPointerException if the specified key is null and this map
|
||||
* does not permit null keys (optional)
|
||||
*/
|
||||
@ -84,8 +83,6 @@ public interface MultiValuedMap<K, V> {
|
||||
*
|
||||
* @param value the value to search for
|
||||
* @return true if the map contains the value
|
||||
* @throws ClassCastException if the type of the specified value is not compatible
|
||||
* with the used collection (optional)
|
||||
* @throws NullPointerException if the value is null and null values are not supported
|
||||
* by the used collection types (optional)
|
||||
*/
|
||||
@ -110,10 +107,9 @@ public interface MultiValuedMap<K, V> {
|
||||
* @param key the key to retrieve
|
||||
* @return the {@code Collection} of values, implementations should
|
||||
* return an empty collection for no mapping
|
||||
* @throws ClassCastException if the key is of an invalid type (optional)
|
||||
* @throws NullPointerException if the key is null and null keys are invalid (optional)
|
||||
*/
|
||||
Collection<V> get(Object key);
|
||||
Collection<V> get(K key);
|
||||
|
||||
// Modification operations
|
||||
|
||||
@ -135,7 +131,6 @@ public interface MultiValuedMap<K, V> {
|
||||
* type does not allow duplicate values, e.g. when using a Set
|
||||
* @throws UnsupportedOperationException if the put operation is not supported by
|
||||
* this multi-valued map, e.g. if it is unmodifiable
|
||||
* @throws ClassCastException if the key or value is of an invalid type (optional)
|
||||
* @throws NullPointerException if the key or value is null and null is invalid (optional)
|
||||
* @throws IllegalArgumentException if some aspect of the specified key or value prevents
|
||||
* it from being stored in this multi-valued map
|
||||
@ -168,15 +163,13 @@ public interface MultiValuedMap<K, V> {
|
||||
* @param map mappings to be stored in this map, may not be null
|
||||
* @throws UnsupportedOperationException if the {@code putAll} operation is
|
||||
* not supported by this map
|
||||
* @throws ClassCastException if the class of a key or value in the
|
||||
* specified map prevents it from being stored in this map (optional)
|
||||
* @throws NullPointerException if the specified map is null, or if this map
|
||||
* does not permit null keys or values, and the specified map
|
||||
* contains null keys or values (optional)
|
||||
* @throws IllegalArgumentException if some property of a key or value in
|
||||
* the specified map prevents it from being stored in this map
|
||||
*/
|
||||
void putAll(Map<? extends K, ? extends V> map);
|
||||
boolean putAll(Map<? extends K, ? extends V> map);
|
||||
|
||||
/**
|
||||
* Copies all mappings from the specified map to this multi-valued map
|
||||
@ -192,15 +185,13 @@ public interface MultiValuedMap<K, V> {
|
||||
* @param map mappings to be stored in this map, may not be null
|
||||
* @throws UnsupportedOperationException if the {@code putAll} operation is
|
||||
* not supported by this map
|
||||
* @throws ClassCastException if the class of a key or value in the
|
||||
* specified map prevents it from being stored in this map (optional)
|
||||
* @throws NullPointerException if the specified map is null, or if this map
|
||||
* does not permit null keys or values, and the specified map
|
||||
* contains null keys or values (optional)
|
||||
* @throws IllegalArgumentException if some property of a key or value in
|
||||
* the specified map prevents it from being stored in this map
|
||||
*/
|
||||
void putAll(MultiValuedMap<? extends K, ? extends V> map);
|
||||
boolean putAll(MultiValuedMap<? extends K, ? extends V> map);
|
||||
|
||||
/**
|
||||
* Removes all values associated with the specified key.
|
||||
@ -212,7 +203,6 @@ public interface MultiValuedMap<K, V> {
|
||||
* @param key the key to remove values from
|
||||
* @return the values that were removed
|
||||
* @throws UnsupportedOperationException if the map is unmodifiable
|
||||
* @throws ClassCastException if the key is of an invalid type (optional)
|
||||
* @throws NullPointerException if the key is null and null keys are invalid (optional)
|
||||
*/
|
||||
Collection<V> remove(Object key);
|
||||
@ -230,10 +220,9 @@ public interface MultiValuedMap<K, V> {
|
||||
* @param item the item to remove
|
||||
* @return true if the mapping was removed, false otherwise
|
||||
* @throws UnsupportedOperationException if the map is unmodifiable
|
||||
* @throws ClassCastException if the key or value is of an invalid type (optional)
|
||||
* @throws NullPointerException if the key or value is null and null is invalid (optional)
|
||||
*/
|
||||
boolean removeMapping(K key, V item);
|
||||
boolean removeMapping(Object key, Object item);
|
||||
|
||||
/**
|
||||
* Removes all of the mappings from this map (optional operation).
|
||||
|
@ -39,14 +39,13 @@ public interface SetValuedMap<K, V> extends MultiValuedMap<K, V> {
|
||||
* have been mapped to the key.
|
||||
* <p>
|
||||
*
|
||||
* @param key the key to retrieve
|
||||
* @param key the key to retrieve
|
||||
* @return the {@code Set} of values, implementations should return an
|
||||
* empty {@code Set} for no mapping
|
||||
* @throws ClassCastException if the key is of an invalid type
|
||||
* @throws NullPointerException if the key is null and null keys are invalid
|
||||
*/
|
||||
@Override
|
||||
Set<V> get(Object key);
|
||||
Set<V> get(K key);
|
||||
|
||||
/**
|
||||
* Removes all values associated with the specified key.
|
||||
@ -55,11 +54,10 @@ public interface SetValuedMap<K, V> extends MultiValuedMap<K, V> {
|
||||
* propagated to this set-valued map. In case no mapping was stored for the
|
||||
* specified key, an empty, unmodifiable set will be returned.
|
||||
*
|
||||
* @param key the key to remove values from
|
||||
* @param key the key to remove values from
|
||||
* @return the {@code Set} of values removed, implementations should
|
||||
* return null for no mapping found, but may return an empty collection
|
||||
* @throws UnsupportedOperationException if the map is unmodifiable
|
||||
* @throws ClassCastException if the key is of an invalid type
|
||||
* @throws NullPointerException if the key is null and null keys are invalid
|
||||
*/
|
||||
@Override
|
||||
|
@ -18,11 +18,9 @@ package org.apache.commons.collections4.multimap;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.collections4.ListUtils;
|
||||
import org.apache.commons.collections4.ListValuedMap;
|
||||
@ -41,14 +39,14 @@ public abstract class AbstractListValuedMap<K, V> extends AbstractMultiValuedMap
|
||||
implements ListValuedMap<K, V> {
|
||||
|
||||
/** The serialization version */
|
||||
private static final long serialVersionUID = 6024950625989666915L;
|
||||
private static final long serialVersionUID = 20150612L;
|
||||
|
||||
/**
|
||||
* A constructor that wraps, not copies
|
||||
*
|
||||
* @param <C> the list type
|
||||
* @param map the map to wrap, must not be null
|
||||
* @param listClazz the collection class
|
||||
* @param map the map to wrap, must not be null
|
||||
* @param listClazz the collection class
|
||||
* @throws NullPointerException if the map is null
|
||||
*/
|
||||
protected <C extends List<V>> AbstractListValuedMap(final Map<K, ? super C> map, Class<C> listClazz) {
|
||||
@ -59,27 +57,35 @@ public abstract class AbstractListValuedMap<K, V> extends AbstractMultiValuedMap
|
||||
* A constructor that wraps, not copies
|
||||
*
|
||||
* @param <C> the list type
|
||||
* @param map the map to wrap, must not be null
|
||||
* @param listClazz the collection class
|
||||
* @param initialListCapacity the initial size of the values list
|
||||
* @throws NullPointerException if the map is null
|
||||
* @throws IllegalArgumentException if initialListCapacity is negative
|
||||
* @param map the map to wrap, must not be null
|
||||
* @param listClazz the collection class
|
||||
* @param initialListCapacity the initial size of the values list
|
||||
* @throws NullPointerException if the map is null
|
||||
* @throws IllegalArgumentException if initialListCapacity is negative
|
||||
*/
|
||||
protected <C extends List<V>> AbstractListValuedMap(final Map<K, ? super C> map, Class<C> listClazz,
|
||||
final int initialListCapacity) {
|
||||
super(map, listClazz, initialListCapacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new value collection using the provided factory.
|
||||
* @return a new list
|
||||
*/
|
||||
@Override
|
||||
protected List<V> createCollection() {
|
||||
return (List<V>) super.createCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of values associated with the specified key. This would
|
||||
* return an empty list in case the mapping is not present
|
||||
*
|
||||
* @param key the key to retrieve
|
||||
* @return the <code>List</code> of values, will return an empty {@link List} for no mapping
|
||||
* @throws ClassCastException if the key is of an invalid type
|
||||
* @param key the key to retrieve
|
||||
* @return the {@code List} of values, will return an empty {@link List} for no mapping
|
||||
*/
|
||||
@Override
|
||||
public List<V> get(Object key) {
|
||||
public List<V> get(final K key) {
|
||||
return new WrappedList(key);
|
||||
}
|
||||
|
||||
@ -88,10 +94,9 @@ public abstract class AbstractListValuedMap<K, V> extends AbstractMultiValuedMap
|
||||
* <p>
|
||||
* A subsequent <code>get(Object)</code> would return an empty list.
|
||||
*
|
||||
* @param key the key to remove values from
|
||||
* @param key the key to remove values from
|
||||
* @return the <code>List</code> of values removed, will return an empty,
|
||||
* unmodifiable list for no mapping found.
|
||||
* @throws ClassCastException if the key is of an invalid type
|
||||
* unmodifiable list for no mapping found.
|
||||
*/
|
||||
@Override
|
||||
public List<V> remove(Object key) {
|
||||
@ -103,42 +108,15 @@ public abstract class AbstractListValuedMap<K, V> extends AbstractMultiValuedMap
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
if (obj instanceof ListValuedMap) {
|
||||
return asMap().equals(((ListValuedMap<?, ?>) obj).asMap());
|
||||
}
|
||||
if (obj instanceof ListValuedMap == false) {
|
||||
return false;
|
||||
}
|
||||
ListValuedMap<?, ?> other = (ListValuedMap<?, ?>) obj;
|
||||
if (other.size() != size()) {
|
||||
return false;
|
||||
}
|
||||
Iterator<?> it = keySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Object key = it.next();
|
||||
List<?> list = get(key);
|
||||
List<?> otherList = other.get(key);
|
||||
if (otherList == null) {
|
||||
return false;
|
||||
}
|
||||
if (ListUtils.isEqualList(list, otherList) == false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int h = 0;
|
||||
Iterator<Entry<K, Collection<V>>> it = getMap().entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Entry<K, Collection<V>> entry = it.next();
|
||||
K key = entry.getKey();
|
||||
List<V> valueList = (List<V>) entry.getValue();
|
||||
h += (key == null ? 0 : key.hashCode()) ^ ListUtils.hashCodeForList(valueList);
|
||||
}
|
||||
return h;
|
||||
return asMap().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -146,60 +124,70 @@ public abstract class AbstractListValuedMap<K, V> extends AbstractMultiValuedMap
|
||||
*/
|
||||
private class WrappedList extends WrappedCollection implements List<V> {
|
||||
|
||||
public WrappedList(Object key) {
|
||||
public WrappedList(final K key) {
|
||||
super(key);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected List<V> getMapping() {
|
||||
return (List<V>) getMap().get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, V value) {
|
||||
List<V> list = (List<V>) getMapping();
|
||||
List<V> list = getMapping();
|
||||
if (list == null) {
|
||||
list = (List<V>) AbstractListValuedMap.this.createCollection();
|
||||
list.add(index, value);
|
||||
getMap().put((K) key, list);
|
||||
list = createCollection();
|
||||
getMap().put(key, list);
|
||||
}
|
||||
list.add(index, value);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public boolean addAll(int index, Collection<? extends V> c) {
|
||||
List<V> list = (List<V>) getMapping();
|
||||
List<V> list = getMapping();
|
||||
if (list == null) {
|
||||
list = (List<V>) createCollection();
|
||||
boolean result = list.addAll(index, c);
|
||||
if (result) {
|
||||
getMap().put((K) key, list);
|
||||
list = createCollection();
|
||||
boolean changed = list.addAll(index, c);
|
||||
if (changed) {
|
||||
getMap().put(key, list);
|
||||
}
|
||||
return result;
|
||||
return changed;
|
||||
}
|
||||
return list.addAll(index, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(int index) {
|
||||
final List<V> list = ListUtils.emptyIfNull((List<V>) getMapping());
|
||||
final List<V> list = ListUtils.emptyIfNull(getMapping());
|
||||
return list.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object o) {
|
||||
final List<V> list = ListUtils.emptyIfNull((List<V>) getMapping());
|
||||
final List<V> list = ListUtils.emptyIfNull(getMapping());
|
||||
return list.indexOf(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object o) {
|
||||
final List<V> list = ListUtils.emptyIfNull((List<V>) getMapping());
|
||||
return list.indexOf(o);
|
||||
final List<V> list = ListUtils.emptyIfNull(getMapping());
|
||||
return list.lastIndexOf(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator<V> listIterator() {
|
||||
return new ValuesListIterator(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator<V> listIterator(int index) {
|
||||
return new ValuesListIterator(key, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V remove(int index) {
|
||||
final List<V> list = ListUtils.emptyIfNull((List<V>) getMapping());
|
||||
final List<V> list = ListUtils.emptyIfNull(getMapping());
|
||||
V value = list.remove(index);
|
||||
if (list.isEmpty()) {
|
||||
AbstractListValuedMap.this.remove(key);
|
||||
@ -207,101 +195,100 @@ public abstract class AbstractListValuedMap<K, V> extends AbstractMultiValuedMap
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V set(int index, V value) {
|
||||
final List<V> list = ListUtils.emptyIfNull((List<V>) getMapping());
|
||||
final List<V> list = ListUtils.emptyIfNull(getMapping());
|
||||
return list.set(index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<V> subList(int fromIndex, int toIndex) {
|
||||
final List<V> list = ListUtils.emptyIfNull((List<V>) getMapping());
|
||||
final List<V> list = ListUtils.emptyIfNull(getMapping());
|
||||
return list.subList(fromIndex, toIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
final List<V> list = (List<V>) getMapping();
|
||||
final List<V> list = getMapping();
|
||||
if (list == null) {
|
||||
return Collections.emptyList().equals(other);
|
||||
}
|
||||
if (other == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(other instanceof List)) {
|
||||
return false;
|
||||
}
|
||||
List<?> otherList = (List<?>) other;
|
||||
if (ListUtils.isEqualList(list, otherList) == false) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return ListUtils.isEqualList(list, otherList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final List<V> list = (List<V>) getMapping();
|
||||
if (list == null) {
|
||||
return Collections.emptyList().hashCode();
|
||||
}
|
||||
final List<V> list = getMapping();
|
||||
return ListUtils.hashCodeForList(list);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Values ListItrerator */
|
||||
private class ValuesListIterator implements ListIterator<V>{
|
||||
|
||||
private final Object key;
|
||||
/** Values ListIterator */
|
||||
private class ValuesListIterator implements ListIterator<V> {
|
||||
|
||||
private final K key;
|
||||
private List<V> values;
|
||||
private ListIterator<V> iterator;
|
||||
|
||||
public ValuesListIterator(Object key){
|
||||
public ValuesListIterator(final K key) {
|
||||
this.key = key;
|
||||
this.values = ListUtils.emptyIfNull((List<V>) getMap().get(key));
|
||||
this.iterator = values.listIterator();
|
||||
}
|
||||
|
||||
public ValuesListIterator(Object key, int index){
|
||||
public ValuesListIterator(final K key, int index) {
|
||||
this.key = key;
|
||||
this.values = ListUtils.emptyIfNull((List<V>) getMap().get(key));
|
||||
this.iterator = values.listIterator(index);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void add(V value) {
|
||||
if (getMap().get(key) == null) {
|
||||
List<V> list = (List<V>) createCollection();
|
||||
getMap().put((K) key, list);
|
||||
List<V> list = createCollection();
|
||||
getMap().put(key, list);
|
||||
this.values = list;
|
||||
this.iterator = list.listIterator();
|
||||
}
|
||||
this.iterator.add(value);
|
||||
this.iterator.add(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return iterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrevious() {
|
||||
return iterator.hasPrevious();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V next() {
|
||||
return iterator.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextIndex() {
|
||||
return iterator.nextIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V previous() {
|
||||
return iterator.previous();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int previousIndex() {
|
||||
return iterator.previousIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
iterator.remove();
|
||||
if (values.isEmpty()) {
|
||||
@ -309,6 +296,7 @@ public abstract class AbstractListValuedMap<K, V> extends AbstractMultiValuedMap
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(V value) {
|
||||
iterator.set(value);
|
||||
}
|
||||
|
@ -50,10 +50,10 @@ import org.apache.commons.collections4.set.UnmodifiableSet;
|
||||
* @since 4.1
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Serializable {
|
||||
public abstract class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Serializable {
|
||||
|
||||
/** Serialization Version */
|
||||
private static final long serialVersionUID = 7994988366330224277L;
|
||||
private static final long serialVersionUID = 20150612L;
|
||||
|
||||
/** The factory for creating value collections. */
|
||||
private final Factory<? extends Collection<V>> collectionFactory;
|
||||
@ -73,7 +73,7 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
/**
|
||||
* Constructor that wraps (not copies).
|
||||
*
|
||||
* @param <C> the collection type
|
||||
* @param <C> the collection type
|
||||
* @param map the map to wrap, must not be null
|
||||
* @param collectionClazz the collection class
|
||||
* @throws NullPointerException if the map is null
|
||||
@ -92,11 +92,11 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
* Constructor that wraps (not copies).
|
||||
*
|
||||
* @param <C> the collection type
|
||||
* @param map the map to wrap, must not be null
|
||||
* @param collectionClazz the collection class
|
||||
* @param initialCollectionCapacity the initial capacity of the collection
|
||||
* @throws NullPointerException if the map is null
|
||||
* @throws IllegalArgumentException if initialCollectionCapacity is negative
|
||||
* @param map the map to wrap, must not be null
|
||||
* @param collectionClazz the collection class
|
||||
* @param initialCollectionCapacity the initial capacity of the collection
|
||||
* @throws NullPointerException if the map is null
|
||||
* @throws IllegalArgumentException if initialCollectionCapacity is negative
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <C extends Collection<V>> AbstractMultiValuedMap(final Map<K, ? super C> map,
|
||||
@ -105,10 +105,11 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
throw new NullPointerException("Map must not be null.");
|
||||
}
|
||||
if (initialCollectionCapacity < 0) {
|
||||
throw new IllegalArgumentException("Illegal Capacity: " + initialCollectionCapacity);
|
||||
throw new IllegalArgumentException("InitialCapacity must not be negative.");
|
||||
}
|
||||
this.map = (Map<K, Collection<V>>) map;
|
||||
this.collectionFactory = new InstantiateFactory<C>(collectionClazz, new Class[] { Integer.TYPE },
|
||||
this.collectionFactory = new InstantiateFactory<C>(collectionClazz,
|
||||
new Class[] { Integer.TYPE },
|
||||
new Object[] { Integer.valueOf(initialCollectionCapacity) });
|
||||
}
|
||||
|
||||
@ -121,45 +122,22 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
return getMap().containsKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean containsValue(final Object value) {
|
||||
final Set<Map.Entry<K, Collection<V>>> pairs = getMap().entrySet();
|
||||
if (pairs != null) {
|
||||
for (final Map.Entry<K, Collection<V>> entry : pairs) {
|
||||
if (entry.getValue().contains(value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return values().contains(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean containsMapping(Object key, Object value) {
|
||||
final Collection<V> col = getMap().get(key);
|
||||
if (col == null) {
|
||||
return false;
|
||||
}
|
||||
return col.contains(value);
|
||||
Collection<V> coll = getMap().get(key);
|
||||
return coll != null && coll.contains(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Collection<Entry<K, V>> entries() {
|
||||
return entryValuesView != null ? entryValuesView : (entryValuesView = new EntryValues());
|
||||
@ -170,12 +148,11 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
* would return an empty collection in case the mapping is not present
|
||||
*
|
||||
* @param key the key to retrieve
|
||||
* @return the <code>Collection</code> of values, will return an empty
|
||||
* <code>Collection</code> for no mapping
|
||||
* @throws ClassCastException if the key is of an invalid type
|
||||
* @return the {@code Collection} of values, will return an empty {@code Collection} for no mapping
|
||||
*/
|
||||
@Override
|
||||
public Collection<V> get(Object key) {
|
||||
public Collection<V> get(final K key) {
|
||||
// TODO: wrap collection based on class type - needed for proper equals
|
||||
return new WrappedCollection(key);
|
||||
}
|
||||
|
||||
@ -184,10 +161,9 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
* <p>
|
||||
* A subsequent <code>get(Object)</code> would return an empty collection.
|
||||
*
|
||||
* @param key the key to remove values from
|
||||
* @param key the key to remove values from
|
||||
* @return the <code>Collection</code> of values removed, will return an
|
||||
* empty, unmodifiable collection for no mapping found.
|
||||
* @throws ClassCastException if the key is of an invalid type
|
||||
* empty, unmodifiable collection for no mapping found
|
||||
*/
|
||||
@Override
|
||||
public Collection<V> remove(Object key) {
|
||||
@ -195,58 +171,46 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a specific value from map.
|
||||
* Removes a specific key/value mapping from the multi-valued map.
|
||||
* <p>
|
||||
* The item is removed from the collection mapped to the specified key.
|
||||
* The value is removed from the collection mapped to the specified key.
|
||||
* Other values attached to that key are unaffected.
|
||||
* <p>
|
||||
* If the last value for a key is removed, an empty collection would be
|
||||
* returned from a subsequent <code>get(Object)</code>.
|
||||
* returned from a subsequent {@link #get(Object)}.
|
||||
*
|
||||
* @param key the key to remove from
|
||||
* @param item the item to remove
|
||||
* @return {@code true} if the mapping was removed, {@code false} otherwise
|
||||
* @param value the value to remove
|
||||
* @return true if the mapping was removed, false otherwise
|
||||
*/
|
||||
@Override
|
||||
public boolean removeMapping(K key, V item) {
|
||||
boolean result = false;
|
||||
final Collection<V> col = getMap().get(key);
|
||||
if (col == null) {
|
||||
public boolean removeMapping(final Object key, final Object value) {
|
||||
final Collection<V> coll = getMap().get(key);
|
||||
if (coll == null) {
|
||||
return false;
|
||||
}
|
||||
result = col.remove(item);
|
||||
if (!result) {
|
||||
return false;
|
||||
boolean changed = coll.remove(value);
|
||||
if (coll.isEmpty()) {
|
||||
getMap().remove(key);
|
||||
}
|
||||
if (col.isEmpty()) {
|
||||
remove(key);
|
||||
}
|
||||
return true;
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return getMap().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Set<K> keySet() {
|
||||
return getMap().keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int size() {
|
||||
// TODO: cache the total size
|
||||
int size = 0;
|
||||
for (Collection<V> col : getMap().values()) {
|
||||
for (final Collection<V> col : getMap().values()) {
|
||||
size += col.size();
|
||||
}
|
||||
return size;
|
||||
@ -265,9 +229,6 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
return vs != null ? vs : (valuesView = new Values());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void clear() {
|
||||
getMap().clear();
|
||||
@ -284,21 +245,19 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
* @return the value added if the map changed and null if the map did not change
|
||||
*/
|
||||
@Override
|
||||
public boolean put(K key, V value) {
|
||||
boolean result = false;
|
||||
public boolean put(final K key, final V value) {
|
||||
Collection<V> coll = getMap().get(key);
|
||||
if (coll == null) {
|
||||
coll = createCollection();
|
||||
coll.add(value);
|
||||
if (coll.size() > 0) {
|
||||
// only add if non-zero size to maintain class state
|
||||
if (coll.add(value)) {
|
||||
getMap().put(key, coll);
|
||||
result = true; // map definitely changed
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
result = coll.add(value);
|
||||
return coll.add(value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -309,15 +268,19 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
* undefined if the specified map is modified while the operation is in
|
||||
* progress.
|
||||
*
|
||||
* @param map mappings to be stored in this map
|
||||
* @param map mappings to be stored in this map, may not be null
|
||||
* @throws NullPointerException if map is null
|
||||
*/
|
||||
@Override
|
||||
public void putAll(final Map<? extends K, ? extends V> map) {
|
||||
if (map != null) {
|
||||
for (final Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
|
||||
put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
public boolean putAll(final Map<? extends K, ? extends V> map) {
|
||||
if (map == null) {
|
||||
throw new NullPointerException("Map must not be null.");
|
||||
}
|
||||
boolean changed = false;
|
||||
for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
|
||||
changed |= put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -328,15 +291,19 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
* behavior of this operation is undefined if the specified map is modified
|
||||
* while the operation is in progress.
|
||||
*
|
||||
* @param map mappings to be stored in this map
|
||||
* @param map mappings to be stored in this map, may not be null
|
||||
* @throws NullPointerException if map is null
|
||||
*/
|
||||
@Override
|
||||
public void putAll(MultiValuedMap<? extends K, ? extends V> map) {
|
||||
if (map != null) {
|
||||
for (final K key : map.keySet()) {
|
||||
putAll(key, map.get(key));
|
||||
}
|
||||
public boolean putAll(final MultiValuedMap<? extends K, ? extends V> map) {
|
||||
if (map == null) {
|
||||
throw new NullPointerException("Map must not be null.");
|
||||
}
|
||||
boolean changed = false;
|
||||
for (Map.Entry<? extends K, ? extends V> entry : map.entries()) {
|
||||
changed |= put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -355,9 +322,6 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
: (keysMultiSetView = new KeysMultiSet());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Map<K, Collection<V>> asMap() {
|
||||
return getMap();
|
||||
@ -377,42 +341,19 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
throw new NullPointerException("Values must not be null.");
|
||||
}
|
||||
|
||||
Iterator<? extends V> it = values.iterator();
|
||||
if (!it.hasNext()) {
|
||||
return false;
|
||||
}
|
||||
boolean result = false;
|
||||
Collection<V> coll = getMap().get(key);
|
||||
if (coll == null) {
|
||||
coll = createCollection(); // might produce a non-empty collection
|
||||
while (it.hasNext()) {
|
||||
coll.add(it.next());
|
||||
}
|
||||
if (coll.size() > 0) {
|
||||
// only add if non-zero size to maintain class state
|
||||
getMap().put(key, coll);
|
||||
result = true; // map definitely changed
|
||||
}
|
||||
if (values instanceof Collection<?>) {
|
||||
Collection<? extends V> valueCollection = (Collection<? extends V>) values;
|
||||
return !valueCollection.isEmpty() && get(key).addAll(valueCollection);
|
||||
} else {
|
||||
while (it.hasNext()) {
|
||||
boolean tmpResult = coll.add(it.next());
|
||||
if (!result && tmpResult) {
|
||||
// If any one of the values have been added, the map has
|
||||
// changed
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
Iterator<? extends V> it = values.iterator();
|
||||
return it.hasNext() && CollectionUtils.addAll(get(key), it);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public MapIterator<K, V> mapIterator() {
|
||||
if (size() == 0) {
|
||||
return EmptyMapIterator.<K, V>emptyMapIterator();
|
||||
return EmptyMapIterator.emptyMapIterator();
|
||||
}
|
||||
return new MultiValuedMapIterator();
|
||||
}
|
||||
@ -422,52 +363,15 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
if (obj instanceof MultiValuedMap) {
|
||||
return asMap().equals(((MultiValuedMap<?, ?>) obj).asMap());
|
||||
}
|
||||
if (obj instanceof MultiValuedMap == false) {
|
||||
return false;
|
||||
}
|
||||
MultiValuedMap<?, ?> other = (MultiValuedMap<?, ?>) obj;
|
||||
if (other.size() != size()) {
|
||||
return false;
|
||||
}
|
||||
Iterator<?> it = keySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Object key = it.next();
|
||||
Collection<?> col = get(key);
|
||||
Collection<?> otherCol = other.get(key);
|
||||
if (otherCol == null) {
|
||||
return false;
|
||||
}
|
||||
if (CollectionUtils.isEqualCollection(col, otherCol) == false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int h = 0;
|
||||
Iterator<Entry<K, Collection<V>>> it = getMap().entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Entry<K, Collection<V>> entry = it.next();
|
||||
K key = entry.getKey();
|
||||
Collection<V> valueCol = entry.getValue();
|
||||
int vh = 0;
|
||||
if (valueCol != null) {
|
||||
Iterator<V> colIt = valueCol.iterator();
|
||||
while (colIt.hasNext()) {
|
||||
V val = colIt.next();
|
||||
if (val != null) {
|
||||
vh += val.hashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
h += (key == null ? 0 : key.hashCode()) ^ vh;
|
||||
}
|
||||
return h;
|
||||
return getMap().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -488,9 +392,9 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
*/
|
||||
protected class WrappedCollection implements Collection<V> {
|
||||
|
||||
protected final Object key;
|
||||
protected final K key;
|
||||
|
||||
public WrappedCollection(Object key) {
|
||||
public WrappedCollection(final K key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@ -499,30 +403,30 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean add(V value) {
|
||||
final Collection<V> col = getMapping();
|
||||
if (col == null) {
|
||||
return AbstractMultiValuedMap.this.put((K) key, value);
|
||||
Collection<V> coll = getMapping();
|
||||
if (coll == null) {
|
||||
coll = createCollection();
|
||||
AbstractMultiValuedMap.this.map.put(key, coll);
|
||||
}
|
||||
return col.add(value);
|
||||
return coll.add(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean addAll(Collection<? extends V> c) {
|
||||
final Collection<V> col = getMapping();
|
||||
if (col == null) {
|
||||
return AbstractMultiValuedMap.this.putAll((K) key, c);
|
||||
public boolean addAll(Collection<? extends V> other) {
|
||||
Collection<V> coll = getMapping();
|
||||
if (coll == null) {
|
||||
coll = createCollection();
|
||||
AbstractMultiValuedMap.this.map.put(key, coll);
|
||||
}
|
||||
return col.addAll(c);
|
||||
return coll.addAll(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
final Collection<V> col = getMapping();
|
||||
if (col != null) {
|
||||
col.clear();
|
||||
final Collection<V> coll = getMapping();
|
||||
if (coll != null) {
|
||||
coll.clear();
|
||||
AbstractMultiValuedMap.this.remove(key);
|
||||
}
|
||||
}
|
||||
@ -530,8 +434,8 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Iterator<V> iterator() {
|
||||
final Collection<V> col = getMapping();
|
||||
if (col == null) {
|
||||
final Collection<V> coll = getMapping();
|
||||
if (coll == null) {
|
||||
return IteratorUtils.EMPTY_ITERATOR;
|
||||
}
|
||||
return new ValuesIterator(key);
|
||||
@ -539,49 +443,37 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
final Collection<V> col = getMapping();
|
||||
if (col == null) {
|
||||
return 0;
|
||||
}
|
||||
return col.size();
|
||||
final Collection<V> coll = getMapping();
|
||||
return coll == null ? 0 : coll.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
final Collection<V> col = getMapping();
|
||||
if (col == null) {
|
||||
return false;
|
||||
}
|
||||
return col.contains(o);
|
||||
public boolean contains(Object obj) {
|
||||
final Collection<V> coll = getMapping();
|
||||
return coll == null ? false : coll.contains(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> o) {
|
||||
final Collection<V> col = getMapping();
|
||||
if (col == null) {
|
||||
return false;
|
||||
}
|
||||
return col.containsAll(o);
|
||||
public boolean containsAll(Collection<?> other) {
|
||||
final Collection<V> coll = getMapping();
|
||||
return coll == null ? false : coll.containsAll(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
final Collection<V> col = getMapping();
|
||||
if (col == null) {
|
||||
return true;
|
||||
}
|
||||
return col.isEmpty();
|
||||
final Collection<V> coll = getMapping();
|
||||
return coll == null ? true : coll.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object item) {
|
||||
final Collection<V> col = getMapping();
|
||||
if (col == null) {
|
||||
final Collection<V> coll = getMapping();
|
||||
if (coll == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean result = col.remove(item);
|
||||
if (col.isEmpty()) {
|
||||
boolean result = coll.remove(item);
|
||||
if (coll.isEmpty()) {
|
||||
AbstractMultiValuedMap.this.remove(key);
|
||||
}
|
||||
return result;
|
||||
@ -589,13 +481,13 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
|
||||
@Override
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
final Collection<V> col = getMapping();
|
||||
if (col == null) {
|
||||
final Collection<V> coll = getMapping();
|
||||
if (coll == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean result = col.removeAll(c);
|
||||
if (col.isEmpty()) {
|
||||
boolean result = coll.removeAll(c);
|
||||
if (coll.isEmpty()) {
|
||||
AbstractMultiValuedMap.this.remove(key);
|
||||
}
|
||||
return result;
|
||||
@ -603,13 +495,13 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
|
||||
@Override
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
final Collection<V> col = getMapping();
|
||||
if (col == null) {
|
||||
final Collection<V> coll = getMapping();
|
||||
if (coll == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean result = col.retainAll(c);
|
||||
if (col.isEmpty()) {
|
||||
boolean result = coll.retainAll(c);
|
||||
if (coll.isEmpty()) {
|
||||
AbstractMultiValuedMap.this.remove(key);
|
||||
}
|
||||
return result;
|
||||
@ -617,36 +509,36 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
final Collection<V> col = getMapping();
|
||||
if (col == null) {
|
||||
final Collection<V> coll = getMapping();
|
||||
if (coll == null) {
|
||||
return CollectionUtils.EMPTY_COLLECTION.toArray();
|
||||
}
|
||||
return col.toArray();
|
||||
return coll.toArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T[] toArray(T[] a) {
|
||||
final Collection<V> col = getMapping();
|
||||
if (col == null) {
|
||||
final Collection<V> coll = getMapping();
|
||||
if (coll == null) {
|
||||
return (T[]) CollectionUtils.EMPTY_COLLECTION.toArray(a);
|
||||
}
|
||||
return col.toArray(a);
|
||||
return coll.toArray(a);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final Collection<V> col = getMapping();
|
||||
if (col == null) {
|
||||
final Collection<V> coll = getMapping();
|
||||
if (coll == null) {
|
||||
return CollectionUtils.EMPTY_COLLECTION.toString();
|
||||
}
|
||||
return col.toString();
|
||||
return coll.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Inner class that provides a MultiSet<K> keys view
|
||||
* Inner class that provides a MultiSet<K> keys view.
|
||||
*/
|
||||
private class KeysMultiSet implements MultiSet<K> {
|
||||
|
||||
@ -749,7 +641,7 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
|
||||
@Override
|
||||
public Set<K> uniqueSet() {
|
||||
return UnmodifiableSet.<K>unmodifiableSet(keySet());
|
||||
return UnmodifiableSet.unmodifiableSet(keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -863,7 +755,7 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
}
|
||||
|
||||
/**
|
||||
* Inner class for MultiValuedMap Entries
|
||||
* Inner class for MultiValuedMap Entries.
|
||||
*/
|
||||
private class MultiValuedMapEntry extends AbstractMapEntry<K, V> {
|
||||
|
||||
@ -879,7 +771,7 @@ public class AbstractMultiValuedMap<K, V> implements MultiValuedMap<K, V>, Seria
|
||||
}
|
||||
|
||||
/**
|
||||
* Inner class for MapIterator
|
||||
* Inner class for MapIterator.
|
||||
*/
|
||||
private class MultiValuedMapIterator implements MapIterator<K, V> {
|
||||
|
||||
|
@ -39,11 +39,11 @@ import org.apache.commons.collections4.MultiValuedMap;
|
||||
* @since 4.1
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AbstractMultiValuedMapDecorator<K, V>
|
||||
public abstract class AbstractMultiValuedMapDecorator<K, V>
|
||||
implements MultiValuedMap<K, V>, Serializable {
|
||||
|
||||
/** Serialization version */
|
||||
private static final long serialVersionUID = -9184930955231260637L;
|
||||
private static final long serialVersionUID = 20150612L;
|
||||
|
||||
/** MultiValuedMap to decorate */
|
||||
private final MultiValuedMap<K, V> map;
|
||||
@ -51,7 +51,7 @@ public class AbstractMultiValuedMapDecorator<K, V>
|
||||
/**
|
||||
* Constructor that wraps (not copies).
|
||||
*
|
||||
* @param map the map to decorate, must not be null
|
||||
* @param map the map to decorate, must not be null
|
||||
* @throws NullPointerException if the map is null
|
||||
*/
|
||||
protected AbstractMultiValuedMapDecorator(final MultiValuedMap<K, V> map) {
|
||||
@ -61,6 +61,11 @@ public class AbstractMultiValuedMapDecorator<K, V>
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
/**
|
||||
* The decorated multi-valued map.
|
||||
*
|
||||
* @return the map to decorate
|
||||
*/
|
||||
protected MultiValuedMap<K, V> decorated() {
|
||||
return map;
|
||||
}
|
||||
@ -76,32 +81,32 @@ public class AbstractMultiValuedMapDecorator<K, V>
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
public boolean containsKey(final Object key) {
|
||||
return decorated().containsKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
public boolean containsValue(final Object value) {
|
||||
return decorated().containsValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsMapping(Object key, Object value) {
|
||||
public boolean containsMapping(final Object key, final Object value) {
|
||||
return decorated().containsMapping(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<V> get(Object key) {
|
||||
public Collection<V> get(final K key) {
|
||||
return decorated().get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<V> remove(Object key) {
|
||||
public Collection<V> remove(final Object key) {
|
||||
return decorated().remove(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeMapping(K key, V item) {
|
||||
public boolean removeMapping(final Object key, final Object item) {
|
||||
return decorated().removeMapping(key, item);
|
||||
}
|
||||
|
||||
@ -146,13 +151,13 @@ public class AbstractMultiValuedMapDecorator<K, V>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<? extends K, ? extends V> m) {
|
||||
decorated().putAll(m);
|
||||
public boolean putAll(Map<? extends K, ? extends V> map) {
|
||||
return decorated().putAll(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(MultiValuedMap<? extends K, ? extends V> m) {
|
||||
decorated().putAll(m);
|
||||
public boolean putAll(MultiValuedMap<? extends K, ? extends V> map) {
|
||||
return decorated().putAll(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -16,12 +16,9 @@
|
||||
*/
|
||||
package org.apache.commons.collections4.multimap;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.collections4.SetUtils;
|
||||
import org.apache.commons.collections4.SetValuedMap;
|
||||
@ -36,17 +33,18 @@ import org.apache.commons.collections4.SetValuedMap;
|
||||
* @since 4.1
|
||||
* @version $Id$
|
||||
*/
|
||||
public abstract class AbstractSetValuedMap<K, V> extends AbstractMultiValuedMap<K, V> implements SetValuedMap<K, V> {
|
||||
public abstract class AbstractSetValuedMap<K, V> extends AbstractMultiValuedMap<K, V>
|
||||
implements SetValuedMap<K, V> {
|
||||
|
||||
/** Serialization version */
|
||||
private static final long serialVersionUID = 3383617478898639862L;
|
||||
private static final long serialVersionUID = 20150612L;
|
||||
|
||||
/**
|
||||
* A constructor that wraps, not copies
|
||||
*
|
||||
* @param <C> the set type
|
||||
* @param map the map to wrap, must not be null
|
||||
* @param setClazz the collection class
|
||||
* @param map the map to wrap, must not be null
|
||||
* @param setClazz the collection class
|
||||
* @throws NullPointerException if the map is null
|
||||
*/
|
||||
protected <C extends Set<V>> AbstractSetValuedMap(Map<K, ? super C> map, Class<C> setClazz) {
|
||||
@ -57,9 +55,9 @@ public abstract class AbstractSetValuedMap<K, V> extends AbstractMultiValuedMap<
|
||||
* A constructor that wraps, not copies
|
||||
*
|
||||
* @param <C> the set type
|
||||
* @param map the map to wrap, must not be null
|
||||
* @param setClazz the collection class
|
||||
* @param initialSetCapacity the initial size of the values set
|
||||
* @param map the map to wrap, must not be null
|
||||
* @param setClazz the collection class
|
||||
* @param initialSetCapacity the initial size of the values set
|
||||
* @throws NullPointerException if the map is null
|
||||
* @throws IllegalArgumentException if initialSetCapacity is negative
|
||||
*/
|
||||
@ -72,13 +70,12 @@ public abstract class AbstractSetValuedMap<K, V> extends AbstractMultiValuedMap<
|
||||
* Gets the set of values associated with the specified key. This would
|
||||
* return an empty set in case the mapping is not present
|
||||
*
|
||||
* @param key the key to retrieve
|
||||
* @param key the key to retrieve
|
||||
* @return the <code>Set</code> of values, will return an empty
|
||||
* <code>Set</code> for no mapping
|
||||
* @throws ClassCastException if the key is of an invalid type
|
||||
* <code>Set</code> for no mapping
|
||||
*/
|
||||
@Override
|
||||
public Set<V> get(Object key) {
|
||||
public Set<V> get(final K key) {
|
||||
return new WrappedSet(key);
|
||||
}
|
||||
|
||||
@ -89,8 +86,7 @@ public abstract class AbstractSetValuedMap<K, V> extends AbstractMultiValuedMap<
|
||||
*
|
||||
* @param key the key to remove values from
|
||||
* @return the <code>Set</code> of values removed, will return an empty,
|
||||
* unmodifiable set for no mapping found.
|
||||
* @throws ClassCastException if the key is of an invalid type
|
||||
* unmodifiable set for no mapping found.
|
||||
*/
|
||||
@Override
|
||||
public Set<V> remove(Object key) {
|
||||
@ -102,51 +98,24 @@ public abstract class AbstractSetValuedMap<K, V> extends AbstractMultiValuedMap<
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
if (obj instanceof SetValuedMap) {
|
||||
return asMap().equals(((SetValuedMap<?, ?>) obj).asMap());
|
||||
}
|
||||
if (obj instanceof SetValuedMap == false) {
|
||||
return false;
|
||||
}
|
||||
SetValuedMap<?, ?> other = (SetValuedMap<?, ?>) obj;
|
||||
if (other.size() != size()) {
|
||||
return false;
|
||||
}
|
||||
Iterator<?> it = keySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Object key = it.next();
|
||||
Set<?> set = get(key);
|
||||
Set<?> otherSet = other.get(key);
|
||||
if (otherSet == null) {
|
||||
return false;
|
||||
}
|
||||
if (SetUtils.isEqualSet(set, otherSet) == false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int h = 0;
|
||||
Iterator<Entry<K, Collection<V>>> it = getMap().entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Entry<K, Collection<V>> entry = it.next();
|
||||
K key = entry.getKey();
|
||||
Set<V> valueSet = (Set<V>) entry.getValue();
|
||||
h += (key == null ? 0 : key.hashCode()) ^ SetUtils.hashCodeForSet(valueSet);
|
||||
}
|
||||
return h;
|
||||
return asMap().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapped set to handle add and remove on the collection returned by
|
||||
* get(object)
|
||||
* {@code get(Object)}.
|
||||
*/
|
||||
protected class WrappedSet extends WrappedCollection implements Set<V> {
|
||||
|
||||
public WrappedSet(Object key) {
|
||||
public WrappedSet(final K key) {
|
||||
super(key);
|
||||
}
|
||||
|
||||
@ -156,25 +125,16 @@ public abstract class AbstractSetValuedMap<K, V> extends AbstractMultiValuedMap<
|
||||
if (set == null) {
|
||||
return Collections.emptySet().equals(other);
|
||||
}
|
||||
if (other == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(other instanceof Set)) {
|
||||
return false;
|
||||
}
|
||||
Set<?> otherSet = (Set<?>) other;
|
||||
if (SetUtils.isEqualSet(set, otherSet) == false) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return SetUtils.isEqualSet(set, otherSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final Set<V> set = (Set<V>) getMapping();
|
||||
if (set == null) {
|
||||
return Collections.emptySet().hashCode();
|
||||
}
|
||||
return SetUtils.hashCodeForSet(set);
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ import org.apache.commons.collections4.SetValuedMap;
|
||||
public class MultiValuedHashMap<K, V> extends AbstractMultiValuedMap<K, V> {
|
||||
|
||||
/** Serialization Version */
|
||||
private static final long serialVersionUID = -5845183518195365857L;
|
||||
private static final long serialVersionUID = 20150612L;
|
||||
|
||||
/**
|
||||
* The initial capacity used when none specified in constructor.
|
||||
@ -220,13 +220,14 @@ public class MultiValuedHashMap<K, V> extends AbstractMultiValuedMap<K, V> {
|
||||
*/
|
||||
protected <C extends Collection<V>> MultiValuedHashMap(int initialCapacity, float loadFactor,
|
||||
final Class<C> collectionClazz, int initialCollectionCapacity) {
|
||||
super(new HashMap<K, Collection<V>>(initialCapacity, loadFactor), collectionClazz, initialCollectionCapacity);
|
||||
super(new HashMap<K, Collection<V>>(initialCapacity, loadFactor), collectionClazz,
|
||||
initialCollectionCapacity);
|
||||
}
|
||||
|
||||
/** Inner class for ListValuedMap */
|
||||
private static class ListValuedHashMap<K, V> extends AbstractListValuedMap<K, V> {
|
||||
|
||||
private static final long serialVersionUID = 3667581458573135234L;
|
||||
private static final long serialVersionUID = 20150612L;
|
||||
|
||||
public <C extends List<V>> ListValuedHashMap(Class<C> listClazz) {
|
||||
super(new HashMap<K, List<V>>(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR), listClazz);
|
||||
@ -242,7 +243,7 @@ public class MultiValuedHashMap<K, V> extends AbstractMultiValuedMap<K, V> {
|
||||
/** Inner class for SetValuedMap */
|
||||
private static class SetValuedHashMap<K, V> extends AbstractSetValuedMap<K, V> {
|
||||
|
||||
private static final long serialVersionUID = -3817515514829894543L;
|
||||
private static final long serialVersionUID = 20150612L;
|
||||
|
||||
public <C extends Set<V>> SetValuedHashMap(Class<C> setClazz) {
|
||||
super(new HashMap<K, Set<V>>(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR), setClazz);
|
||||
|
@ -17,13 +17,12 @@
|
||||
package org.apache.commons.collections4.multimap;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.FluentIterable;
|
||||
import org.apache.commons.collections4.MultiValuedMap;
|
||||
import org.apache.commons.collections4.Transformer;
|
||||
import org.apache.commons.collections4.map.LinkedMap;
|
||||
|
||||
/**
|
||||
* Decorates another <code>MultiValuedMap</code> to transform objects that are added.
|
||||
@ -41,7 +40,7 @@ import org.apache.commons.collections4.map.LinkedMap;
|
||||
public class TransformedMultiValuedMap<K, V> extends AbstractMultiValuedMapDecorator<K, V> {
|
||||
|
||||
/** Serialization Version */
|
||||
private static final long serialVersionUID = -1254147899086470720L;
|
||||
private static final long serialVersionUID = 20150612L;
|
||||
|
||||
/** The key transformer */
|
||||
private final Transformer<? super K, ? extends K> keyTransformer;
|
||||
@ -56,8 +55,8 @@ public class TransformedMultiValuedMap<K, V> extends AbstractMultiValuedMapDecor
|
||||
* NOT transformed. Contrast this with
|
||||
* {@link #transformedMap(MultiValuedMap, Transformer, Transformer)}.
|
||||
*
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param map the MultiValuedMap to decorate, may not be null
|
||||
* @param keyTransformer the transformer to use for key conversion, null means no conversion
|
||||
* @param valueTransformer the transformer to use for value conversion, null means no conversion
|
||||
@ -78,8 +77,8 @@ public class TransformedMultiValuedMap<K, V> extends AbstractMultiValuedMapDecor
|
||||
* be transformed by this method. Contrast this with
|
||||
* {@link #transformingMap(MultiValuedMap, Transformer, Transformer)}.
|
||||
*
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @param map the MultiValuedMap to decorate, may not be null
|
||||
* @param keyTransformer the transformer to use for key conversion, null means no conversion
|
||||
* @param valueTransformer the transformer to use for value conversion, null means no conversion
|
||||
@ -91,11 +90,10 @@ public class TransformedMultiValuedMap<K, V> extends AbstractMultiValuedMapDecor
|
||||
final Transformer<? super V, ? extends V> valueTransformer) {
|
||||
final TransformedMultiValuedMap<K, V> decorated =
|
||||
new TransformedMultiValuedMap<K, V>(map, keyTransformer, valueTransformer);
|
||||
if (map.size() > 0) {
|
||||
MultiValuedMap<K, V> transformed = decorated.transformMultiValuedMap(map);
|
||||
if (!map.isEmpty()) {
|
||||
final MultiValuedMap<K, V> mapCopy = new MultiValuedHashMap<K, V>(map);
|
||||
decorated.clear();
|
||||
// to avoid double transform
|
||||
decorated.decorated().putAll(transformed);
|
||||
decorated.putAll(mapCopy);
|
||||
}
|
||||
return decorated;
|
||||
}
|
||||
@ -112,8 +110,9 @@ public class TransformedMultiValuedMap<K, V> extends AbstractMultiValuedMapDecor
|
||||
* @param valueTransformer the transformer to use for value conversion, null means no conversion
|
||||
* @throws NullPointerException if map is null
|
||||
*/
|
||||
protected TransformedMultiValuedMap(MultiValuedMap<K, V> map,
|
||||
Transformer<? super K, ? extends K> keyTransformer, Transformer<? super V, ? extends V> valueTransformer) {
|
||||
protected TransformedMultiValuedMap(final MultiValuedMap<K, V> map,
|
||||
final Transformer<? super K, ? extends K> keyTransformer,
|
||||
final Transformer<? super V, ? extends V> valueTransformer) {
|
||||
super(map);
|
||||
this.keyTransformer = keyTransformer;
|
||||
this.valueTransformer = valueTransformer;
|
||||
@ -149,83 +148,44 @@ public class TransformedMultiValuedMap<K, V> extends AbstractMultiValuedMapDecor
|
||||
return valueTransformer.transform(object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a map.
|
||||
* <p>
|
||||
* The transformer itself may throw an exception if necessary.
|
||||
*
|
||||
* @param map the map to transform
|
||||
* @return the transformed object
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Map<K, V> transformMap(final Map<? extends K, ? extends V> map) {
|
||||
if (map.isEmpty()) {
|
||||
return (Map<K, V>) map;
|
||||
}
|
||||
final Map<K, V> result = new LinkedMap<K, V>(map.size());
|
||||
|
||||
for (final Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
|
||||
result.put(transformKey(entry.getKey()), transformValue(entry.getValue()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a MultiValuedMap.
|
||||
* <p>
|
||||
* The transformer itself may throw an exception if necessary.
|
||||
*
|
||||
* @param map the MultiValuedMap to transform
|
||||
* @return the transformed object
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected MultiValuedMap<K, V> transformMultiValuedMap(
|
||||
final MultiValuedMap<? extends K, ? extends V> map) {
|
||||
if (map.isEmpty()) {
|
||||
return (MultiValuedMap<K, V>) map;
|
||||
}
|
||||
final MultiValuedMap<K, V> result = new MultiValuedHashMap<K, V>();
|
||||
|
||||
for (final Map.Entry<? extends K, ? extends V> entry : map.entries()) {
|
||||
result.put(transformKey(entry.getKey()), transformValue(entry.getValue()));
|
||||
}
|
||||
return result;
|
||||
@Override
|
||||
public boolean put(final K key, final V value) {
|
||||
return decorated().put(transformKey(key), transformValue(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean put(K key, V value) {
|
||||
K transformedKey = transformKey(key);
|
||||
V transformedValue = transformValue(value);
|
||||
return decorated().put(transformedKey, transformedValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean putAll(K key, Iterable<? extends V> values) {
|
||||
public boolean putAll(final K key, final Iterable<? extends V> values) {
|
||||
if (values == null) {
|
||||
throw new NullPointerException("Values must not be null.");
|
||||
}
|
||||
|
||||
Iterator<V> it = (Iterator<V>) values.iterator();
|
||||
if (!it.hasNext()) {
|
||||
return false;
|
||||
}
|
||||
K transformedKey = transformKey(key);
|
||||
List<V> transformedValues = new LinkedList<V>();
|
||||
while (it.hasNext()) {
|
||||
transformedValues.add(transformValue(it.next()));
|
||||
}
|
||||
return decorated().putAll(transformedKey, transformedValues);
|
||||
final Iterable<V> transformedValues = FluentIterable.of(values).transform(valueTransformer);
|
||||
final Iterator<? extends V> it = transformedValues.iterator();
|
||||
return it.hasNext() && CollectionUtils.addAll(decorated().get(transformKey(key)), it);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<? extends K, ? extends V> m) {
|
||||
decorated().putAll(transformMap(m));
|
||||
public boolean putAll(final Map<? extends K, ? extends V> map) {
|
||||
if (map == null) {
|
||||
throw new NullPointerException("Map must not be null.");
|
||||
}
|
||||
boolean changed = false;
|
||||
for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
|
||||
changed |= put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(MultiValuedMap<? extends K, ? extends V> m) {
|
||||
decorated().putAll(transformMultiValuedMap(m));
|
||||
public boolean putAll(final MultiValuedMap<? extends K, ? extends V> map) {
|
||||
if (map == null) {
|
||||
throw new NullPointerException("Map must not be null.");
|
||||
}
|
||||
boolean changed = false;
|
||||
for (Map.Entry<? extends K, ? extends V> entry : map.entries()) {
|
||||
changed |= put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -42,19 +42,19 @@ import org.apache.commons.collections4.set.UnmodifiableSet;
|
||||
* @since 4.1
|
||||
* @version $Id$
|
||||
*/
|
||||
public class UnmodifiableMultiValuedMap<K, V>
|
||||
public final class UnmodifiableMultiValuedMap<K, V>
|
||||
extends AbstractMultiValuedMapDecorator<K, V> implements Unmodifiable {
|
||||
|
||||
/** Serialization version */
|
||||
private static final long serialVersionUID = 1418669828214151566L;
|
||||
private static final long serialVersionUID = 20150612L;
|
||||
|
||||
/**
|
||||
* Factory method to create an unmodifiable MultiValuedMap.
|
||||
* <p>
|
||||
* If the map passed in is already unmodifiable, it is returned.
|
||||
*
|
||||
* @param <K> the type of key elements
|
||||
* @param <V> the type of value elements
|
||||
* @param <K> the type of key elements
|
||||
* @param <V> the type of value elements
|
||||
* @param map the map to decorate, may not be null
|
||||
* @return an unmodifiable MultiValuedMap
|
||||
* @throws NullPointerException if map is null
|
||||
@ -80,12 +80,12 @@ public class UnmodifiableMultiValuedMap<K, V>
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<V> remove(Object key) {
|
||||
public Collection<V> remove(final Object key) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeMapping(K key, V item) {
|
||||
public boolean removeMapping(final Object key, final Object item) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@ -95,12 +95,12 @@ public class UnmodifiableMultiValuedMap<K, V>
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<V> get(Object key) {
|
||||
return UnmodifiableCollection.<V>unmodifiableCollection(decorated().get(key));
|
||||
public Collection<V> get(final K key) {
|
||||
return UnmodifiableCollection.unmodifiableCollection(decorated().get(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean put(K key, V value) {
|
||||
public boolean put(final K key, final V value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@ -126,26 +126,26 @@ public class UnmodifiableMultiValuedMap<K, V>
|
||||
|
||||
@Override
|
||||
public Map<K, Collection<V>> asMap() {
|
||||
return UnmodifiableMap.<K, Collection<V>>unmodifiableMap(decorated().asMap());
|
||||
return UnmodifiableMap.unmodifiableMap(decorated().asMap());
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapIterator<K, V> mapIterator() {
|
||||
return UnmodifiableMapIterator.<K, V>unmodifiableMapIterator(decorated().mapIterator());
|
||||
return UnmodifiableMapIterator.unmodifiableMapIterator(decorated().mapIterator());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean putAll(K key, Iterable<? extends V> values) {
|
||||
public boolean putAll(final K key, final Iterable<? extends V> values) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<? extends K, ? extends V> m) {
|
||||
public boolean putAll(final Map<? extends K, ? extends V> map) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(MultiValuedMap<? extends K, ? extends V> m) {
|
||||
public boolean putAll(final MultiValuedMap<? extends K, ? extends V> map) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
@ -192,26 +192,29 @@ public abstract class AbstractMultiValuedMapTest<K, V> extends AbstractObjectTes
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testNoMappingReturnsEmptyCol() {
|
||||
final MultiValuedMap<K, V> map = makeFullMap();
|
||||
assertTrue(map.get("whatever").isEmpty());
|
||||
assertTrue(map.get((K) "whatever").isEmpty());
|
||||
}
|
||||
|
||||
public void testMultipleValues() {
|
||||
final MultiValuedMap<K, V> map = makeFullMap();
|
||||
Collection<V> col = map.get("one");
|
||||
@SuppressWarnings("unchecked")
|
||||
Collection<V> col = map.get((K) "one");
|
||||
assertTrue(col.contains("uno"));
|
||||
assertTrue(col.contains("un"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testGet() {
|
||||
final MultiValuedMap<K, V> map = makeFullMap();
|
||||
assertTrue(map.get("one").contains("uno"));
|
||||
assertTrue(map.get("one").contains("un"));
|
||||
assertTrue(map.get("two").contains("dos"));
|
||||
assertTrue(map.get("two").contains("deux"));
|
||||
assertTrue(map.get("three").contains("tres"));
|
||||
assertTrue(map.get("three").contains("trois"));
|
||||
assertTrue(map.get((K) "one").contains("uno"));
|
||||
assertTrue(map.get((K) "one").contains("un"));
|
||||
assertTrue(map.get((K) "two").contains("dos"));
|
||||
assertTrue(map.get((K) "two").contains("deux"));
|
||||
assertTrue(map.get((K) "three").contains("tres"));
|
||||
assertTrue(map.get((K) "three").contains("trois"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -221,8 +224,8 @@ public abstract class AbstractMultiValuedMapTest<K, V> extends AbstractObjectTes
|
||||
}
|
||||
resetEmpty();
|
||||
final MultiValuedMap<K, V> map = getMap();
|
||||
Collection<V> col1 = map.get("one");
|
||||
Collection<V> col2 = map.get("one");
|
||||
Collection<V> col1 = map.get((K) "one");
|
||||
Collection<V> col2 = map.get((K) "one");
|
||||
assertTrue(col1.isEmpty());
|
||||
assertTrue(col2.isEmpty());
|
||||
assertEquals(0, map.size());
|
||||
@ -243,7 +246,8 @@ public abstract class AbstractMultiValuedMapTest<K, V> extends AbstractObjectTes
|
||||
}
|
||||
resetFull();
|
||||
final MultiValuedMap<K, V> map = getMap();
|
||||
Collection<V> col = map.get("one");
|
||||
@SuppressWarnings("unchecked")
|
||||
Collection<V> col = map.get((K) "one");
|
||||
assertEquals(2, col.size());
|
||||
assertEquals(6, map.size());
|
||||
col.remove("uno");
|
||||
@ -265,7 +269,8 @@ public abstract class AbstractMultiValuedMapTest<K, V> extends AbstractObjectTes
|
||||
}
|
||||
resetFull();
|
||||
final MultiValuedMap<K, V> map = getMap();
|
||||
Iterator<V> it = map.get("one").iterator();
|
||||
@SuppressWarnings("unchecked")
|
||||
Iterator<V> it = map.get((K) "one").iterator();
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
it.remove();
|
||||
@ -325,6 +330,7 @@ public abstract class AbstractMultiValuedMapTest<K, V> extends AbstractObjectTes
|
||||
// assertEquals(expected, actual);
|
||||
// }
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testRemoveAllViaValuesIterator() {
|
||||
if (!isRemoveSupported()) {
|
||||
return;
|
||||
@ -334,7 +340,7 @@ public abstract class AbstractMultiValuedMapTest<K, V> extends AbstractObjectTes
|
||||
i.next();
|
||||
i.remove();
|
||||
}
|
||||
assertTrue(map.get("one").isEmpty());
|
||||
assertTrue(map.get((K) "one").isEmpty());
|
||||
assertTrue(map.isEmpty());
|
||||
}
|
||||
|
||||
@ -392,6 +398,7 @@ public abstract class AbstractMultiValuedMapTest<K, V> extends AbstractObjectTes
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testRemoveAllViaEntriesIterator() {
|
||||
if (!isRemoveSupported()) {
|
||||
return;
|
||||
@ -401,7 +408,7 @@ public abstract class AbstractMultiValuedMapTest<K, V> extends AbstractObjectTes
|
||||
i.next();
|
||||
i.remove();
|
||||
}
|
||||
assertTrue(map.get("one").isEmpty());
|
||||
assertTrue(map.get((K) "one").isEmpty());
|
||||
assertEquals(0, map.size());
|
||||
}
|
||||
|
||||
@ -418,7 +425,7 @@ public abstract class AbstractMultiValuedMapTest<K, V> extends AbstractObjectTes
|
||||
final MultiValuedMap<K, V> one = makeObject();
|
||||
final Integer value = Integer.valueOf(1);
|
||||
one.put((K) "One", (V) value);
|
||||
one.removeMapping((K) "One", (V) value);
|
||||
one.removeMapping("One", value);
|
||||
|
||||
final MultiValuedMap<K, V> two = makeObject();
|
||||
assertEquals(two, one);
|
||||
@ -441,7 +448,7 @@ public abstract class AbstractMultiValuedMapTest<K, V> extends AbstractObjectTes
|
||||
assertEquals(4, map.size());
|
||||
map.remove("A");
|
||||
assertEquals(3, map.size());
|
||||
map.removeMapping((K) "B", (V) "BC");
|
||||
map.removeMapping("B", "BC");
|
||||
assertEquals(2, map.size());
|
||||
}
|
||||
|
||||
@ -453,33 +460,33 @@ public abstract class AbstractMultiValuedMapTest<K, V> extends AbstractObjectTes
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testSize_Key() {
|
||||
final MultiValuedMap<K, V> map = makeFullMap();
|
||||
assertEquals(2, map.get("one").size());
|
||||
assertEquals(2, map.get("two").size());
|
||||
assertEquals(2, map.get("three").size());
|
||||
assertEquals(2, map.get((K) "one").size());
|
||||
assertEquals(2, map.get((K) "two").size());
|
||||
assertEquals(2, map.get((K) "three").size());
|
||||
if (!isAddSupported()) {
|
||||
return;
|
||||
}
|
||||
map.put((K) "A", (V) "AA");
|
||||
assertEquals(1, map.get("A").size());
|
||||
assertEquals(1, map.get((K) "A").size());
|
||||
//assertEquals(0, map.get("B").size());
|
||||
map.put((K) "B", (V) "BA");
|
||||
assertEquals(1, map.get("A").size());
|
||||
assertEquals(1, map.get("B").size());
|
||||
assertEquals(1, map.get((K) "A").size());
|
||||
assertEquals(1, map.get((K) "B").size());
|
||||
map.put((K) "B", (V) "BB");
|
||||
assertEquals(1, map.get("A").size());
|
||||
assertEquals(2, map.get("B").size());
|
||||
assertEquals(1, map.get((K) "A").size());
|
||||
assertEquals(2, map.get((K) "B").size());
|
||||
map.put((K) "B", (V) "BC");
|
||||
assertEquals(1, map.get("A").size());
|
||||
assertEquals(3, map.get("B").size());
|
||||
assertEquals(1, map.get((K) "A").size());
|
||||
assertEquals(3, map.get((K) "B").size());
|
||||
if (!isRemoveSupported()) {
|
||||
return;
|
||||
}
|
||||
map.remove("A");
|
||||
//assertEquals(0, map.get("A").size());
|
||||
assertEquals(3, map.get("B").size());
|
||||
map.removeMapping((K) "B", (V) "BC");
|
||||
assertEquals(3, map.get((K) "B").size());
|
||||
map.removeMapping("B", "BC");
|
||||
//assertEquals(0, map.get("A").size());
|
||||
assertEquals(2, map.get("B").size());
|
||||
assertEquals(2, map.get((K) "B").size());
|
||||
}
|
||||
|
||||
// @SuppressWarnings("unchecked")
|
||||
@ -534,8 +541,8 @@ public abstract class AbstractMultiValuedMapTest<K, V> extends AbstractObjectTes
|
||||
|
||||
assertEquals(2, test.keySet().size());
|
||||
assertEquals(4, test.size());
|
||||
assertEquals(1, test.get("keyA").size());
|
||||
assertEquals(3, test.get("key").size());
|
||||
assertEquals(1, test.get((K) "keyA").size());
|
||||
assertEquals(3, test.get((K) "key").size());
|
||||
assertEquals(true, test.containsValue("objectA"));
|
||||
assertEquals(true, test.containsValue("object0"));
|
||||
assertEquals(true, test.containsValue("object1"));
|
||||
@ -558,9 +565,9 @@ public abstract class AbstractMultiValuedMapTest<K, V> extends AbstractObjectTes
|
||||
|
||||
assertEquals(3, test.keySet().size());
|
||||
assertEquals(4, test.size());
|
||||
assertEquals(1, test.get("keyA").size());
|
||||
assertEquals(2, test.get("keyX").size());
|
||||
assertEquals(1, test.get("keyY").size());
|
||||
assertEquals(1, test.get((K) "keyA").size());
|
||||
assertEquals(2, test.get((K) "keyX").size());
|
||||
assertEquals(1, test.get((K) "keyY").size());
|
||||
assertEquals(true, test.containsValue("objectA"));
|
||||
assertEquals(true, test.containsValue("object0"));
|
||||
assertEquals(true, test.containsValue("object1"));
|
||||
@ -576,7 +583,7 @@ public abstract class AbstractMultiValuedMapTest<K, V> extends AbstractObjectTes
|
||||
Collection<V> coll = (Collection<V>) Arrays.asList("X", "Y", "Z");
|
||||
|
||||
assertEquals(true, map.putAll((K) "A", coll));
|
||||
assertEquals(3, map.get("A").size());
|
||||
assertEquals(3, map.get((K) "A").size());
|
||||
assertEquals(true, map.containsMapping("A", "X"));
|
||||
assertEquals(true, map.containsMapping("A", "Y"));
|
||||
assertEquals(true, map.containsMapping("A", "Z"));
|
||||
@ -588,20 +595,20 @@ public abstract class AbstractMultiValuedMapTest<K, V> extends AbstractObjectTes
|
||||
// expected
|
||||
}
|
||||
|
||||
assertEquals(3, map.get("A").size());
|
||||
assertEquals(3, map.get((K) "A").size());
|
||||
assertEquals(true, map.containsMapping("A", "X"));
|
||||
assertEquals(true, map.containsMapping("A", "Y"));
|
||||
assertEquals(true, map.containsMapping("A", "Z"));
|
||||
|
||||
assertEquals(false, map.putAll((K) "A", new ArrayList<V>()));
|
||||
assertEquals(3, map.get("A").size());
|
||||
assertEquals(3, map.get((K) "A").size());
|
||||
assertEquals(true, map.containsMapping("A", "X"));
|
||||
assertEquals(true, map.containsMapping("A", "Y"));
|
||||
assertEquals(true, map.containsMapping("A", "Z"));
|
||||
|
||||
coll = (Collection<V>) Arrays.asList("M");
|
||||
assertEquals(true, map.putAll((K) "A", coll));
|
||||
assertEquals(4, map.get("A").size());
|
||||
assertEquals(4, map.get((K) "A").size());
|
||||
assertEquals(true, map.containsMapping("A", "X"));
|
||||
assertEquals(true, map.containsMapping("A", "Y"));
|
||||
assertEquals(true, map.containsMapping("A", "Z"));
|
||||
@ -617,11 +624,11 @@ public abstract class AbstractMultiValuedMapTest<K, V> extends AbstractObjectTes
|
||||
map.put((K) "A", (V) "AA");
|
||||
map.put((K) "A", (V) "AB");
|
||||
map.put((K) "A", (V) "AC");
|
||||
assertEquals(false, map.removeMapping((K) "C", (V) "CA"));
|
||||
assertEquals(false, map.removeMapping((K) "A", (V) "AD"));
|
||||
assertEquals(true, map.removeMapping((K) "A", (V) "AC"));
|
||||
assertEquals(true, map.removeMapping((K) "A", (V) "AB"));
|
||||
assertEquals(true, map.removeMapping((K) "A", (V) "AA"));
|
||||
assertEquals(false, map.removeMapping("C", "CA"));
|
||||
assertEquals(false, map.removeMapping("A", "AD"));
|
||||
assertEquals(true, map.removeMapping("A", "AC"));
|
||||
assertEquals(true, map.removeMapping("A", "AB"));
|
||||
assertEquals(true, map.removeMapping("A", "AA"));
|
||||
//assertEquals(new MultiValuedHashMap<K, V>(), map);
|
||||
}
|
||||
|
||||
@ -756,13 +763,15 @@ public abstract class AbstractMultiValuedMapTest<K, V> extends AbstractObjectTes
|
||||
assertEquals("Map is empty", 0, map2.size());
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public void testFullMapCompatibility() throws Exception {
|
||||
final MultiValuedMap<?, ?> map = makeFullMap();
|
||||
final MultiValuedMap<?, ?> map2 =
|
||||
(MultiValuedMap<?, ?>) readExternalFormFromDisk(getCanonicalFullCollectionName(map));
|
||||
final MultiValuedMap map = makeFullMap();
|
||||
final MultiValuedMap map2 =
|
||||
(MultiValuedMap) readExternalFormFromDisk(getCanonicalFullCollectionName(map));
|
||||
assertEquals("Map is the right size", map.size(), map2.size());
|
||||
for (final Object key : map.keySet()) {
|
||||
assertTrue("Map had inequal elements", CollectionUtils.isEqualCollection(map.get(key), map2.get(key)));
|
||||
assertTrue("Map had inequal elements",
|
||||
CollectionUtils.isEqualCollection(map.get(key), map2.get(key)));
|
||||
if (isRemoveSupported()) {
|
||||
map2.remove(key);
|
||||
}
|
||||
|
@ -53,9 +53,9 @@ public class MultiValuedHashMapTest<K, V> extends AbstractMultiValuedMapTest<K,
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testSetValuedMapAdd() {
|
||||
final SetValuedMap<K, V> setMap = MultiValuedHashMap.setValuedHashMap();
|
||||
assertTrue(setMap.get("whatever") instanceof Set);
|
||||
assertTrue(setMap.get((K) "whatever") instanceof Set);
|
||||
|
||||
Set<V> set = setMap.get("A");
|
||||
Set<V> set = setMap.get((K) "A");
|
||||
assertTrue(set.add((V) "a1"));
|
||||
assertTrue(set.add((V) "a2"));
|
||||
assertFalse(set.add((V) "a1"));
|
||||
@ -66,9 +66,9 @@ public class MultiValuedHashMapTest<K, V> extends AbstractMultiValuedMapTest<K,
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testSetValuedMapRemove() {
|
||||
final SetValuedMap<K, V> setMap = MultiValuedHashMap.setValuedHashMap();
|
||||
assertTrue(setMap.get("whatever") instanceof Set);
|
||||
assertTrue(setMap.get((K) "whatever") instanceof Set);
|
||||
|
||||
Set<V> set = setMap.get("A");
|
||||
Set<V> set = setMap.get((K) "A");
|
||||
assertTrue(set.add((V) "a1"));
|
||||
assertTrue(set.add((V) "a2"));
|
||||
assertFalse(set.add((V) "a1"));
|
||||
@ -86,9 +86,9 @@ public class MultiValuedHashMapTest<K, V> extends AbstractMultiValuedMapTest<K,
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testSetValuedMapRemoveViaIterator() {
|
||||
final SetValuedMap<K, V> setMap = MultiValuedHashMap.setValuedHashMap();
|
||||
assertTrue(setMap.get("whatever") instanceof Set);
|
||||
assertTrue(setMap.get((K) "whatever") instanceof Set);
|
||||
|
||||
Set<V> set = setMap.get("A");
|
||||
Set<V> set = setMap.get((K) "A");
|
||||
set.add((V) "a1");
|
||||
set.add((V) "a2");
|
||||
set.add((V) "a1");
|
||||
@ -105,8 +105,8 @@ public class MultiValuedHashMapTest<K, V> extends AbstractMultiValuedMapTest<K,
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testListValuedMapAdd() {
|
||||
final ListValuedMap<K, V> listMap = MultiValuedHashMap.listValuedHashMap();
|
||||
assertTrue(listMap.get("whatever") instanceof List);
|
||||
List<V> list = listMap.get("A");
|
||||
assertTrue(listMap.get((K) "whatever") instanceof List);
|
||||
List<V> list = listMap.get((K) "A");
|
||||
list.add((V) "a1");
|
||||
assertEquals(1, listMap.size());
|
||||
assertTrue(listMap.containsKey("A"));
|
||||
@ -115,7 +115,7 @@ public class MultiValuedHashMapTest<K, V> extends AbstractMultiValuedMapTest<K,
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testListValuedMapAddViaListIterator() {
|
||||
final ListValuedMap<K, V> listMap = MultiValuedHashMap.listValuedHashMap();
|
||||
ListIterator<V> listIt = listMap.get("B").listIterator();
|
||||
ListIterator<V> listIt = listMap.get((K) "B").listIterator();
|
||||
assertFalse(listIt.hasNext());
|
||||
listIt.add((V) "b1");
|
||||
listIt.add((V) "b2");
|
||||
@ -129,7 +129,7 @@ public class MultiValuedHashMapTest<K, V> extends AbstractMultiValuedMapTest<K,
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testListValuedMapRemove() {
|
||||
final ListValuedMap<K, V> listMap = MultiValuedHashMap.listValuedHashMap();
|
||||
List<V> list = listMap.get("A");
|
||||
List<V> list = listMap.get((K) "A");
|
||||
list.add((V) "a1");
|
||||
list.add((V) "a2");
|
||||
list.add((V) "a3");
|
||||
@ -146,12 +146,12 @@ public class MultiValuedHashMapTest<K, V> extends AbstractMultiValuedMapTest<K,
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testListValuedMapRemoveViaListIterator() {
|
||||
final ListValuedMap<K, V> listMap = MultiValuedHashMap.listValuedHashMap();
|
||||
ListIterator<V> listIt = listMap.get("B").listIterator();
|
||||
ListIterator<V> listIt = listMap.get((K) "B").listIterator();
|
||||
listIt.add((V) "b1");
|
||||
listIt.add((V) "b2");
|
||||
assertEquals(2, listMap.size());
|
||||
assertTrue(listMap.containsKey("B"));
|
||||
listIt = listMap.get("B").listIterator();
|
||||
listIt = listMap.get((K) "B").listIterator();
|
||||
while (listIt.hasNext()) {
|
||||
listIt.next();
|
||||
listIt.remove();
|
||||
@ -160,7 +160,7 @@ public class MultiValuedHashMapTest<K, V> extends AbstractMultiValuedMapTest<K,
|
||||
listIt.add((V) "b1");
|
||||
listIt.add((V) "b2");
|
||||
assertTrue(listMap.containsKey("B"));
|
||||
assertEquals(2, listMap.get("B").size());
|
||||
assertEquals(2, listMap.get((K) "B").size());
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@ -170,8 +170,8 @@ public class MultiValuedHashMapTest<K, V> extends AbstractMultiValuedMapTest<K,
|
||||
|
||||
map1.put("a", "a1");
|
||||
map1.put("a", "a2");
|
||||
map2.put("a", "a2");
|
||||
map2.put("a", "a1");
|
||||
map2.put("a", "a2");
|
||||
assertEquals(map1, map2);
|
||||
assertEquals(map1.hashCode(), map2.hashCode());
|
||||
|
||||
|
@ -63,7 +63,7 @@ public class TransformedMultiValuedMapTest<K, V> extends AbstractMultiValuedMapT
|
||||
assertEquals(true, map.containsKey(Integer.valueOf((String) els[i])));
|
||||
assertEquals(false, map.containsKey(els[i]));
|
||||
assertEquals(true, map.containsValue(els[i]));
|
||||
assertEquals(true, map.get(Integer.valueOf((String) els[i])).contains(els[i]));
|
||||
assertEquals(true, map.get((K) Integer.valueOf((String) els[i])).contains(els[i]));
|
||||
}
|
||||
|
||||
Collection<V> coll = map.remove(els[0]);
|
||||
@ -86,7 +86,7 @@ public class TransformedMultiValuedMapTest<K, V> extends AbstractMultiValuedMapT
|
||||
assertEquals(true, map.containsValue(Integer.valueOf((String) els[i])));
|
||||
assertEquals(false, map.containsValue(els[i]));
|
||||
assertEquals(true, map.containsKey(els[i]));
|
||||
assertEquals(true, map.get(els[i]).contains(Integer.valueOf((String) els[i])));
|
||||
assertEquals(true, map.get((K) els[i]).contains(Integer.valueOf((String) els[i])));
|
||||
}
|
||||
assertEquals(true, map.remove(els[0]).contains(Integer.valueOf((String) els[0])));
|
||||
}
|
||||
@ -105,11 +105,11 @@ public class TransformedMultiValuedMapTest<K, V> extends AbstractMultiValuedMapT
|
||||
null,
|
||||
(Transformer<? super V, ? extends V>) TransformedCollectionTest.STRING_TO_INTEGER_TRANSFORMER);
|
||||
assertEquals(3, trans.size());
|
||||
assertEquals(true, trans.get("A").contains("1"));
|
||||
assertEquals(true, trans.get("B").contains("2"));
|
||||
assertEquals(true, trans.get("C").contains("3"));
|
||||
assertEquals(true, trans.get((K) "A").contains("1"));
|
||||
assertEquals(true, trans.get((K) "B").contains("2"));
|
||||
assertEquals(true, trans.get((K) "C").contains("3"));
|
||||
trans.put((K) "D", (V) "4");
|
||||
assertEquals(true, trans.get("D").contains(Integer.valueOf(4)));
|
||||
assertEquals(true, trans.get((K) "D").contains(Integer.valueOf(4)));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -125,11 +125,11 @@ public class TransformedMultiValuedMapTest<K, V> extends AbstractMultiValuedMapT
|
||||
null,
|
||||
(Transformer<? super V, ? extends V>) TransformedCollectionTest.STRING_TO_INTEGER_TRANSFORMER);
|
||||
assertEquals(3, trans.size());
|
||||
assertEquals(true, trans.get("A").contains(Integer.valueOf(1)));
|
||||
assertEquals(true, trans.get("B").contains(Integer.valueOf(2)));
|
||||
assertEquals(true, trans.get("C").contains(Integer.valueOf(3)));
|
||||
assertEquals(true, trans.get((K) "A").contains(Integer.valueOf(1)));
|
||||
assertEquals(true, trans.get((K) "B").contains(Integer.valueOf(2)));
|
||||
assertEquals(true, trans.get((K) "C").contains(Integer.valueOf(3)));
|
||||
trans.put((K) "D", (V) "4");
|
||||
assertEquals(true, trans.get("D").contains(Integer.valueOf(4)));
|
||||
assertEquals(true, trans.get((K) "D").contains(Integer.valueOf(4)));
|
||||
}
|
||||
|
||||
// public void testCreate() throws Exception {
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user