Package net.cscott.jutil
Interface MultiMap<K,V>
- All Superinterfaces:
Map<K,V>
- All Known Subinterfaces:
InvertibleMultiMap<K,V>
- All Known Implementing Classes:
AbstractMultiMap,GenericInvertibleMultiMap,GenericMultiMap,UnmodifiableMultiMap
MultiMap maps a key to a collection of values. These
collections are created as needed using a
CollectionFactory. Any constraints on the
collections produced by this factory thus hold for the values that
this maps to.
Formally, a MultiMap is a Multiple Associative Container. It associates key objects with value objects. The difference between a
MultiMap and a standard
Map is that MultiMap extends the
Map interface to allow for the same key to map to
multiple values.
Thus, the type signature for a MultiMap is :: Map[keytype -> [valtype] ]
Note that an association (known as a (Key, Value) pair or a
Map.Entry in the Java Collections API) is only
defined to exist if the collection of objects mapped to by
some key is non-empty.
This has a number of implications for the behavior of
MultiMap:
Let
-
mmbe aMultiMap, -
kbe anObject(which may or may not be a Key inmm) -
cbe theCollectionreturned bymm.getValues(k).
Then
c will either be a non-empty
Collection (the case where k is a
Key in mm) or it will be an empty collection (the
case where k is not a Key in mm).
In the latter case, however, k is still
considered to not be a Key in mm until
c is made non-empty. We chose to return an
empty Collection instead of null to
allow for straightforward addition to the collection of
values mapped to by k.
To conform to the
Map interface, the
put(key, value) method has a non-intuitive
behavior; it throws away all values previously associated
with key and creates a new mapping from
key to a singleton collection containing
value. Use add(key, value) to
preserve the old collection of associative mappings.
The default methods of
Map which are not
overridden here, such as putIfAbsent(),
computeIfPresent(), compute() and
merge(), are built on get(),
put() and remove(): they see an
arbitrary one of the values of a key, and replace or remove
all of them. replace(Object,Object,Object) and
replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>) treat each mapping separately.
Note that the behavior of MultiMap is
indistinquishable from that of a Map if none of
the extensions of MultiMap are utilized. Thus,
users should take care to ensure that other code relying on
the constraints enforced by the Map interface
does not ever attempt to use a MultiMap when any
of its Keys map to more than one value.
- Author:
- Felix S. Klock II <pnkfelix@mit.edu>
- Tests:
- <code>add()</code> adds a value to those of a key, while <code>put()</code> replaces them all:
js> mm = new GenericMultiMap(Factories.treeSetFactory()) {} js> mm.add("fruit", "pear"); mm.add("fruit", "apple") true js> mm.add("nut", "pecan") true js> mm.getValues("fruit") [apple, pear] js> mm.size() // the number of mappings, not of keys 3 js> mm.put("fruit", "fig") // returns one of the old values apple js> mm.getValues("fruit") [fig]
-
Nested Class Summary
-
Method Summary
Modifier and TypeMethodDescriptionbooleanEnsures thatthiscontains an association fromkeytovalue.booleanaddAll(K key, Collection<? extends V> values) Adds to the current mappings: associations forkeyto each value invalues.booleanAdds all mappings in the given multimap to this multimap.booleanReturns true ifahas a mapping tobinthis.entrySet()Returns some arbitrary value from the collection of values to which this map maps the specified key.Returns the collection of Values associated withkey.Associates the specified value with the specified key in this map, after removing all old values associated with the key.voidCopies the mappings from the specified map to this map, after removing all old values associated with the key.Removes mappings from key to all associated values from this map.booleanRemoves a mapping from key to value from this map if presentbooleanremoveAll(K key, Collection<?> values) Removes from the current mappings: associations forkeyto any value invalues.default booleanReplaces the mapping fromkeytooldValue, if there is one, with a mapping fromkeytonewValue.default voidreplaceAll(BiFunction<? super K, ? super V, ? extends V> function) Replaces each mapping from a keykto a valuevwith a mapping fromktofunction.apply(k, v).booleanretainAll(K key, Collection<?> values) Removes from the current mappings: associations forkeyto any value not invalues.intsize()Returns the number of key-value mappings in this map (keys which map to multiple values count multiple times).Methods inherited from interface java.util.Map
clear, compute, computeIfAbsent, computeIfPresent, containsKey, containsValue, equals, forEach, getOrDefault, hashCode, isEmpty, keySet, merge, putIfAbsent, replace, values
-
Method Details
-
get
Returns some arbitrary value from the collection of values to which this map maps the specified key. Returnsnullif the map contains no mapping for the key; it's also possible that the map explicitly maps the key tonull. ThecontainsKeyoperation may be used to distinquish these two cases. Note that if only theputmethod is used to modifythis, thengetwill operate just as it would in any otherMap. -
put
Associates the specified value with the specified key in this map, after removing all old values associated with the key. Returns some value that was previously associated with the specified key, ornullif no values were associated previously. -
putAll
Copies the mappings from the specified map to this map, after removing all old values associated with the key. Note thatputAll(mm)wheremmis aMultiMapwill NOT add all of the mappings inmm; it will only add all of the Keys inmm, mapping each Key to one of the Values it mapped to inmm. To add all of the mappings from anotherMultiMap, useaddAll(MultiMap). -
remove
Removes mappings from key to all associated values from this map. This is consistent with theMapdefinition ofremove.- Specified by:
removein interfaceMap<K,V> - Returns:
- one of the previous values associated with the key,
or
nullifMapassociated no values with the key. Note that a zero-sized collection is not returned in the latter case, and that anullreturn value may be ambiguous if the map associatednullwith the given key (in addition to possibly other values).
-
remove
Removes a mapping from key to value from this map if present. (MultiMapspecific operation). Note that if multiple mappings from key to value are permitted by this map, then only one is guaranteed to be removed. Returns true ifthiswas modified as a result of this operation, else returns false. -
add
- Returns:
trueif this mapping changed as a result of the call
-
addAll
Adds to the current mappings: associations forkeyto each value invalues. (MultiMapspecific operation).- Returns:
trueif this mapping changed as a result of the call
-
addAll
Adds all mappings in the given multimap to this multimap. -
retainAll
Removes from the current mappings: associations forkeyto any value not invalues. (MultiMapspecific operation).- Returns:
trueif this mapping changed as a result of the call
-
removeAll
Removes from the current mappings: associations forkeyto any value invalues. (MultiMapspecific operation).- Returns:
trueif this mapping changed as a result of the call
-
getValues
Returns the collection of Values associated withkey. Modifications to the returnedCollectionaffectthisas well. If there are no Values currently associated withkey, constructs a new, potentially mutable, emptyCollectionand returns it. (MultiMapspecific operation). -
contains
-
size
int size()Returns the number of key-value mappings in this map (keys which map to multiple values count multiple times). -
entrySet
MultiMapSet<K,V> entrySet() -
replace
Replaces the mapping fromkeytooldValue, if there is one, with a mapping fromkeytonewValue. The other values ofkeyare kept. (Map's default implementation would compareoldValueto an arbitrary one of the values ofkey, and then replace all of them.) -
replaceAll
Replaces each mapping from a keykto a valuevwith a mapping fromktofunction.apply(k, v). The new mappings are added after all of the new values are computed, so this map is unchanged iffunctionthrows. (Map's default implementation would callMap.Entry.setValue(V)while iterating, which aMultiMap's entries do not support.)- Specified by:
replaceAllin interfaceMap<K,V> - Since:
- 2.0
-