
ru.progrm_jarvis.javacommons.collection.MapUtil Maven / Gradle / Ivy
package ru.progrm_jarvis.javacommons.collection;
import lombok.NonNull;
import lombok.experimental.UtilityClass;
import lombok.val;
import lombok.var;
import ru.progrm_jarvis.javacommons.object.Pair;
import java.util.Iterator;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;
/**
* Utilities related to {@link Map}.
*/
@UtilityClass
public class MapUtil {
/**
* Fills the map not performing any checks.
*
* @param map map to fill
* @param keyValuePairs key-value pairs to put to the map ordered as key1, value1, key2, value2...
*/
@SuppressWarnings("unchecked")
private void fillMapNoChecks(@SuppressWarnings("rawtypes") final @NonNull Map map,
final @NonNull Object... keyValuePairs) {
@SuppressWarnings("BooleanVariableAlwaysNegated") var value = true; // will get reverted for the first value
Object key = null; // requires to be initialized for some reason :)
for (final Object keyValuePair : keyValuePairs) if (value = !value) map.put(key, keyValuePair);
else key = keyValuePair;
}
/**
* Fills the map specified with the values specified.
*
* @param map map to fill with the values
* @param keyValuePairs pairs of keys and values in order key1, value1, key2, value2, key3, value3...
* @param map type
* @return the map passed filled with key-value pairs specified
* @throws IllegalArgumentException if {@code keyValuePairs}'s length is odd
*
* @see #fillMap(Map, Object, Object, Object...)
*/
public > M fillMap(final @NonNull M map, final @NonNull Object... keyValuePairs) {
val length = keyValuePairs.length;
if (length == 0) return map;
if (length % 2 != 0) throw new IllegalArgumentException(
"Key-Value pairs array should have an even number of elements"
);
fillMapNoChecks(map, keyValuePairs);
return map;
}
/**
* Fills the map specified with the values specified.
*
* @param map map to fill with the values
* @param firstValueKey the key of first value
* @param firstValue first value to be put to the map
* @param keyValuePairs pairs of keys and values in order key1, value1, key2, value2, key3, value3...
* @param type of keys
* @param type of values
* @param map type
* @return the map passed filled with key-value pairs specified
* @throws IllegalArgumentException if {@code keyValuePairs}'s length is odd
*
* @see #fillMap(Map, Object...)
*/
public > M fillMap(final @NonNull M map, final K firstValueKey, final V firstValue,
final @NonNull Object... keyValuePairs) {
val length = keyValuePairs.length;
if(length % 2 != 0) throw new IllegalArgumentException(
"Key-Value pairs array should have an even number of elements"
);
map.put(firstValueKey, firstValue);
fillMapNoChecks(map, keyValuePairs);
return map;
}
/**
* Fills the map specified with the values specified.
*
* @param map map to fill with the values
* @param entries entries to fill the map with
* @param type of keys
* @param type of values
* @param map type
* @return the map passed filled with key-value pairs specified
*/
@SafeVarargs
public > M fillMap(final @NonNull M map, final @NonNull Pair... entries) {
for (val entry : entries) map.put(entry.getFirst(), entry.getSecond());
return map;
}
/**
* Fills the map specified with the values specified.
*
* @param map map to fill with the values
* @param entries entries to fill the map with
* @param type of keys
* @param type of values
* @param map type
* @return the map passed filled with key-value pairs specified
*/
public > M fillMap(final @NonNull M map,
final @NonNull Iterator extends Pair> entries) {
while (entries.hasNext()) {
val entry = entries.next();
map.put(entry.getFirst(), entry.getSecond());
}
return map;
}
/**
* Fills the map specified with the values specified.
*
* @param map map to fill with the values
* @param entries entries to fill the map with
* @param type of keys
* @param type of values
* @param map type
* @return the map passed filled with key-value pairs specified
*/
public > M fillMap(final @NonNull M map,
final @NonNull Iterable extends Pair> entries) {
return fillMap(map, entries.iterator());
}
/**
* Fills the map specified with the values specified.
*
* @param map map to fill with the values
* @param entries entries to fill the map with
* @param type of keys
* @param type of values
* @param map type
* @return the map passed filled with key-value pairs specified
*/
public > M fillMap(final @NonNull M map,
final @NonNull Stream extends Pair> entries) {
entries.forEach(entry -> map.put(entry.getFirst(), entry.getSecond()));
return map;
}
/**
* Fills the map specified with the values specified keeping order.
*
* @param map map to fill with the values
* @param entries entries to fill the map with
* @param type of keys
* @param type of values
* @param map type
* @return the map passed filled with key-value pairs specified
*/
public > M fillMapOrdered(final @NonNull M map,
final @NonNull Stream extends Pair> entries) {
entries.forEachOrdered(entry -> map.put(entry.getFirst(), entry.getSecond()));
return map;
}
public V getOrDefault(final @NonNull Map map, final K key, final Supplier defaultValueSupplier) {
// the value is got from map, non-null value is surely a present one, but null may have different meanings
val value = map.get(key);
return value == null ? map.containsKey(key) ? null : defaultValueSupplier.get() : value;
}
public R getOrDefault(final @NonNull Map map, final K key, final Function valueTransformer,
final R defaultValue) {
// the value is got from map, non-null value is surely a present one, but null may have different meanings
val value = map.get(key);
return value == null
? map.containsKey(key) ? valueTransformer.apply(null) : defaultValue
: valueTransformer.apply(value);
}
public R getOrDefault(final @NonNull Map map, final K key, final Function valueTransformer,
final Supplier defaultValueSupplier) {
// the value is got from map, non-null value is surely a present one, but null may have different meanings
val value = map.get(key);
return value == null
? map.containsKey(key) ? valueTransformer.apply(null) : defaultValueSupplier.get()
: valueTransformer.apply(value);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy