
norswap.utils.multimap.MultiMap Maven / Gradle / Ivy
Show all versions of utils Show documentation
package norswap.utils.multimap;
import norswap.utils.data.wrappers.Pair;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Stream;
/**
* An extension of a regular {@code K -> Collection} map to enable/improve its use as a multimap:
* a map from {@code K} to a collection of invididual {@code V} values.
*/
public interface MultiMap extends Map>
{
// ---------------------------------------------------------------------------------------------
/**
* Return an unmodifiable view of the collection of values to which {@code key} is mapped, or an
* empty collection if there is no mapping for the key.
*
* Also see {@link Map#get} for more details. Notably, when this method returns an
* empty collection, there may be no mapping for the key, or there may be a mapping from the key
* to an empty collection.
*/
@Override Collection get (Object key);
// ---------------------------------------------------------------------------------------------
/**
* Removes the mapping for {@code key} from the map, if present.
*
* @return An unmodifiable view of the collection of values previously associated with the key,
* or an empty map if not values were associated with the key.
*/
@Override Collection remove(Object key);
// ---------------------------------------------------------------------------------------------
/**
* Associates {@code value} with {@code key}, while preserving all other associated values.
*
* @return The collection of values associated with the key after the operation has taken place.
*/
Collection add (K key, V value);
// ---------------------------------------------------------------------------------------------
/**
* Removes the given key-value pair from the multimap. If the pair is the last for the given
* key, remove the underlying collection.
*
* @return The collection of values associated with the key after the operation has taken place.
*/
Collection delete (K key, V value);
// ---------------------------------------------------------------------------------------------
/**
* Removes the given key-value pair from the multimap. If the pair is the last for the given
* key, does not remove the underlying collection.
*
* @return The collection of values associated with the key after the operation has taken place.
*/
Collection deletePollute (K key, V value);
// ---------------------------------------------------------------------------------------------
/**
* Associates all values in {@code values}, while preserving all other associated values.
*
* @return The collection of values associated with the key after the operation has taken place.
*/
Collection addAll (K key, V[] values);
// ---------------------------------------------------------------------------------------------
/**
* Associates all values in {@code values}, while preserving all other associated values.
*
* @return The collection of values associated with the key after the operation has taken place.
*/
Collection addAll (K key, Iterable values);
// ---------------------------------------------------------------------------------------------
/**
* Returns a stream enumerating all the (key, value) pairs in the multimap (i.e, keys are
* repeated for each associated value).
*/
Stream> pairs();
// ---------------------------------------------------------------------------------------------
/**
* Associates all values in {@code values}, while preserving all other associated values.
*
* @return The collection of values associated with the key after the operation has taken place.
*/
default Collection addAll (K key, Collection values)
{
return addAll(key, (Iterable) values);
}
// ---------------------------------------------------------------------------------------------
/**
* Returns a flattened collection containing all the values associated with all keys in the
* multimap.
*/
default Collection allValues()
{
ArrayList out = new ArrayList<>();
for (Collection col: values()) out.addAll(col);
return out;
}
// ---------------------------------------------------------------------------------------------
/**
* Adds all key-value pairs from {@code singleMap} into this multimap (as per {@link
* #add(Object, Object)}).
*/
default void add (Map singleMap)
{
for (Entry e: singleMap.entrySet())
add(e.getKey(), e.getValue());
}
// ---------------------------------------------------------------------------------------------
/**
* Adds all key-value associations from {@code multiMap} into this multimap (as per {@link
* #addAll(Object, Collection)}. This basically merges {@code multiMap} inside the receiver.
*/
default void add (MultiMap multiMap)
{
for (Entry> e: multiMap.entrySet())
addAll(e.getKey(), e.getValue());
}
// ---------------------------------------------------------------------------------------------
/**
* For each item in {@code items}, apply the function {@code f} and insert the resulting
* binding into the multi map, before returning it.
*/
default MultiMap assoc (Iterable items, Function> f)
{
for (X item: items) {
Pair pair = f.apply(item);
if (pair == null) continue;
add(pair.a, pair.b);
}
return this;
}
// ---------------------------------------------------------------------------------------------
/**
* For each item in {@code items}, apply the function {@code f} and insert the resulting
* binding into the multi map, before returning it.
*/
default MultiMap assoc (X[] items, Function> f)
{
for (X item: items) {
Pair pair = f.apply(item);
if (pair == null) continue;
add(pair.a, pair.b);
}
return this;
}
// ---------------------------------------------------------------------------------------------
/**
* Returns a {@link Collector} that extracts keys and values from each item and this entry
* to the multimap.
*/
static MultiMapCollector
collector (Function keyExtractor, Function valueExtractor) {
return new MultiMapCollector<>(false, keyExtractor, valueExtractor);
}
// ---------------------------------------------------------------------------------------------
/**
* Returns a {@link Collector} that extracts keys and values from each item and this entry
* to the multimap.
*
* The returned multimap will be a {@link MultiHashSetMap}, so values will be automatically
* de-duplicated.
*/
static MultiMapCollector
setCollector (Function keyExtractor, Function valueExtractor) {
return new MultiMapCollector<>(true, keyExtractor, valueExtractor);
}
// ---------------------------------------------------------------------------------------------
}