package org.ovirt.engine.core.utils.collections;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* A utility class for manipulating maps that have a value of a {@link List} type.
*/
public class MultiValueMapUtils {
/** A private constructor to prohibit instantiation */
private MultiValueMapUtils() {
}
/**
* Adds an additional {@link #value} to the given {@link #key} in the {@link #map}.
*
* If a collection of values was already associated with this key, the new value is added to its end.
* It's assumed that the existing list implementation is mutable.
*
* If there is no collection associated with this value, a new collection containing the value will be created.
*
* @param key The key of the map to which the value should be added.
* @param value The value to add to the map
* @param map The map to have the value added
* @param creator A factory to create the new (empty) collection for the values to be held
*/
public static <K, V, C extends Collection<V>> void addToMap(K key,
V value,
Map<K, C> map,
CollectionCreator<V, C> creator) {
C existingValues = map.get(key);
if (existingValues == null) {
existingValues = creator.create();
map.put(key, existingValues);
}
existingValues.add(value);
}
/**
* Same as {@link #addToMap(Object, Object, Map, CollectionCreator)}, with the default {@link ArrayList} to hold the values.
*/
public static <K, V> void addToMap(K key, V value, Map<K, List<V>> map) {
addToMap(key, value, map, new ListCreator<>());
}
public static <K, V> void addToMapOfSets(K key, V value, Map<K, Set<V>> map) {
addToMap(key, value, map, new SetCreator<>());
}
public static interface CollectionCreator<V, C extends Collection<V>> {
C create();
}
public static class ListCreator<V> implements CollectionCreator<V, List<V>> {
@Override
public List<V> create() {
return new ArrayList<>();
}
}
public static class ArrayListCreator<V> implements CollectionCreator<V, ArrayList<V>> {
@Override
public ArrayList<V> create() {
return new ArrayList<>();
}
}
public static class LinkedListCreator<V> implements CollectionCreator<V, LinkedList<V>> {
@Override
public LinkedList<V> create() {
return new LinkedList<>();
}
}
public static class SetCreator<V> implements CollectionCreator<V, Set<V>> {
@Override
public Set<V> create() {
return new HashSet<>();
}
}
public static class HashSetCreator<V> implements CollectionCreator<V, HashSet<V>> {
@Override
public HashSet<V> create() {
return new HashSet<>();
}
}
public static class LinkedHashSetCreator<V> implements CollectionCreator<V, Set<V>> {
@Override
public Set<V> create() {
return new LinkedHashSet<>();
}
}
public static <K, V, C extends Collection<V>> boolean removeFromMap(Map<K, C> map, K key, V value) {
C collection = map.get(key);
if (collection == null) {
return false;
}
boolean success = collection.remove(value);
if (success && collection.size() == 0) {
return map.remove(key) != null;
}
return success;
}
}