
no.mnemonic.commons.utilities.collections.MapUtils Maven / Gradle / Ivy
package no.mnemonic.commons.utilities.collections;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
public class MapUtils {
private MapUtils() {
}
/**
* Creates a map from a map
*
* @param map Map to create new map from
* @param Type of keys.
* @param Type of values.
* @return A new map containing the entries of the provided map, or an empty map if the provided argument was null
*/
public static Map map(Map map) {
if (map == null) return new HashMap<>();
return new HashMap<>(map);
}
/**
* Creates a map from key-value pairs.
*
* @param pairs Pairs converted to key-value entries in the map.
* @param Type of keys.
* @param Type of values.
* @return A map containing the key-value pairs.
*/
@SafeVarargs
public static Map map(Pair... pairs) {
if (pairs == null) return new HashMap<>();
return map(Arrays.asList(pairs));
}
/**
* Creates a map from an iterator supplying key-value pairs.
*
* @param iterator An iterator supplying key-value pairs which are added to the map.
* @param Type of keys.
* @param Type of values.
* @return A map containing all key-value pairs supplied by the given iterator.
*/
public static Map map(Iterator> iterator) {
return map(iterator, p -> p);
}
/**
* Creates a map from a collection containing key-value pairs.
*
* @param collection A collection containing key-value pairs which are added to the map.
* @param Type of keys.
* @param Type of values.
* @return A map containing all key-value pairs contained in the given collection.
*/
public static Map map(Collection> collection) {
return map(collection, p -> p);
}
/**
* Creates a map from its arguments using a mapping function to extract key-value pairs.
*
* @param mapping A mapping function applied to all values to extract key-value pairs.
* @param values Values which are added to the map.
* @param Type of keys.
* @param Type of values.
* @param Type of argument values.
* @return A map containing all key-value pairs extracted from the values.
*/
@SafeVarargs
public static Map map(Function> mapping, T... values) {
if (values == null) return new HashMap<>();
return map(Arrays.asList(values), mapping);
}
/**
* Creates a map from an iterator using a mapping function to extract key-value pairs.
*
* @param iterator An iterator which values are added to the map.
* @param mapping A mapping function applied to all values supplied by 'iterator' to extract key-value pairs.
* @param Type of keys.
* @param Type of values.
* @param Type of elements supplied by 'iterator'.
* @return A map containing all key-value pairs extracted from the given iterator.
*/
public static Map map(Iterator iterator, Function> mapping) {
if (mapping == null) throw new IllegalArgumentException("Mapping function not set!");
if (iterator == null) return new HashMap<>();
Map result = new HashMap<>();
iterator.forEachRemaining(o -> {
Pair p = mapping.apply(o);
result.put(p.fst, p.snd);
});
return result;
}
/**
* Creates a map from a collection using a mapping function to extract key-value pairs.
*
* @param collection A collection which values are added to the map.
* @param mapping A mapping function applied to all values contained in 'collection' to extract key-value pairs.
* @param Type of keys.
* @param Type of values.
* @param Type of elements in 'collection'.
* @return A map containing all key-value pairs extracted from the given collection.
*/
public static Map map(Collection collection, Function> mapping) {
if (mapping == null) throw new IllegalArgumentException("Mapping function not set!");
if (collection == null) return new HashMap<>();
Map result = new HashMap<>();
collection.forEach(o -> {
Pair p = mapping.apply(o);
result.put(p.fst, p.snd);
});
return result;
}
/**
* Adds a key-value pair to a map unless the key or the value are null.
*
* A new map is created if the provided map is null.
*
* @param map Map to which the key-value pair will be added.
* @param key Key in the map.
* @param value Value added for the given key.
* @param Type of keys.
* @param Type of values.
* @return Map including added key-value pair.
*/
public static Map addToMap(Map map, K key, V value) {
if (map == null) map = new HashMap<>();
if (key == null || value == null) return map;
map.put(key, value);
return map;
}
/**
* Concatenates multiple maps into one new map.
*
* If the same key exists in multiple maps the value stored in the last map will be used.
*
* @param maps Multiple maps which will be concatenated.
* @param Type of keys.
* @param Type of values.
* @return A map containing all key-value pairs from the given maps.
*/
@SafeVarargs
public static Map concatenate(Map... maps) {
if (maps == null) return new HashMap<>();
Map result = new HashMap<>();
for (Map m : maps) {
if (m != null) result.putAll(m);
}
return result;
}
/**
* Applies add/remove modifications to a map.
*
* This operation permits adding to and removing from one map in a single operation.
*
* @param originMap Map to be modified.
* @param addMap Map containing key-value pairs to be added.
* @param removeKeys Collection containing keys to be removed.
* @param Type of keys.
* @param Type of values.
* @return Same instance of 'originMap' passed in after modification.
*/
public static Map modifyMap(Map originMap, Map addMap, Collection removeKeys) {
if (originMap == null) return null;
if (!isEmpty(addMap)) originMap.putAll(addMap);
if (!CollectionUtils.isEmpty(removeKeys)) removeKeys.forEach(originMap::remove);
return originMap;
}
/**
* Creates a subset of the given map based on a collection of keys. The original map is not altered.
*
* @param originMap Map to be filtered.
* @param retainKeys Keys to retain in subset map.
* @param Type of keys.
* @param Type of values.
* @return A new map containing only the keys listed in 'retainKeys'.
*/
public static Map filterMap(Map originMap, Collection retainKeys) {
if (originMap == null || retainKeys == null) return new HashMap<>();
return originMap
.entrySet()
.stream()
.filter(e -> retainKeys.contains(e.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
/**
* Null-safe operation to test if a map is empty.
*
* @param map Map to be tested.
* @param Type of keys in map.
* @param Type of values in map.
* @return Returns true if the map is null or contains no elements.
*/
public static boolean isEmpty(Map map) {
return map == null || map.isEmpty();
}
/**
* Null-safe operation to determine the size of a map.
*
* @param map Map to compute size for.
* @param Type of keys in map.
* @param Type of values in map.
* @return Returns 0 if the map is null, otherwise the number of elements in the map.
*/
public static int size(Map map) {
return map == null ? 0 : map.size();
}
/**
* Convenience method to create a key/value {@link Pair}.
*
* @param key Key
* @param val Value
* @param Type of key
* @param Type of value
* @return A key/value pair
*/
public static Pair pair(K key, V val) {
return Pair.T(key, val);
}
public final static class Pair {
private final A fst;
private final B snd;
private Pair(A fst, B snd) {
this.fst = fst;
this.snd = snd;
}
public static Pair T(A fst, B snd) {
return new Pair<>(fst, snd);
}
}
}