aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/utils/MapUtil.java
diff options
context:
space:
mode:
Diffstat (limited to 'catalog-dao/src/main/java/org/openecomp/sdc/be/dao/utils/MapUtil.java')
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/utils/MapUtil.java230
1 files changed, 139 insertions, 91 deletions
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/utils/MapUtil.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/utils/MapUtil.java
index e8b2e0c9ad..5b0ad9cc24 100644
--- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/utils/MapUtil.java
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/utils/MapUtil.java
@@ -7,9 +7,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,105 +20,153 @@
package org.openecomp.sdc.be.dao.utils;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
+import java.util.*;
+import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import static java.util.stream.Collectors.toList;
/**
* Utility class to ease map manipulation.
*/
public final class MapUtil {
- private MapUtil() {
- }
+ private MapUtil() {
+ }
- /**
- * Try to get a value following a path in the map. For example :
- * MapUtil.get(map, "a.b.c") correspond to: map.get(a).get(b).get(c)
- *
- * @param map
- * the map to search for path
- * @param path
- * keys in the map separated by '.'
- */
- public static Object get(Map<String, ? extends Object> map, String path) {
- String[] tokens = path.split("\\.");
- if (tokens.length == 0) {
- return null;
- } else {
- Object value = map;
- for (String token : tokens) {
- if (!(value instanceof Map)) {
- return null;
- } else {
- @SuppressWarnings("unchecked")
- Map<String, Object> nested = (Map<String, Object>) value;
- if (nested.containsKey(token)) {
- value = nested.get(token);
- } else {
- return null;
- }
- }
- }
- return value;
- }
- }
+ /**
+ * Try to get a value following a path in the map. For example :
+ * MapUtil.get(map, "a.b.c") correspond to: map.get(a).get(b).get(c)
+ *
+ * @param map the map to search for path
+ * @param path keys in the map separated by '.'
+ */
+ public static Object get(Map<String, ? extends Object> map, String path) {
+ String[] tokens = path.split("\\.");
+ if (tokens.length == 0) {
+ return null;
+ } else {
+ Object value = map;
+ for (String token : tokens) {
+ if (!(value instanceof Map)) {
+ return null;
+ } else {
+ @SuppressWarnings("unchecked")
+ Map<String, Object> nested = (Map<String, Object>) value;
+ if (nested.containsKey(token)) {
+ value = nested.get(token);
+ } else {
+ return null;
+ }
+ }
+ }
+ return value;
+ }
+ }
- /**
- *
- * @param valuesToMap the list of values to group
- * @param groupingFunction the function to group the list values by
- * @return a map of list of values grouped by a key, as specified in the {@code groupingFunction}
- */
- public static <K,V> Map<K,List<V>> groupListBy(Collection<V> valuesToMap, Function<V,K> groupingFunction) {
- return valuesToMap.stream().collect(Collectors.groupingBy(groupingFunction));
- }
+ /**
+ * @param valuesToMap the list of values to group
+ * @param groupingFunction the function to group the list values by
+ * @return a map of list of values grouped by a key, as specified in the {@code groupingFunction}
+ */
+ public static <K, V> Map<K, List<V>> groupListBy(Collection<V> valuesToMap, Function<V, K> groupingFunction) {
+ return valuesToMap.stream().collect(Collectors.groupingBy(groupingFunction));
+ }
- /**
- *
- * @param valuesToMap list of values to map
- * @param mappingFunction a function which specifies how to map each element on the list
- * @return a map created by mapping each element from the {@code valuesToMap} as specified in the {@code mappingFunction}
- */
- public static <K,V> Map<K,V> toMap(Collection<V> valuesToMap, Function<V,K> mappingFunction) {
- return Optional.ofNullable(valuesToMap).orElse(new ArrayList<>()).stream().collect(Collectors.toMap(mappingFunction, Function.identity()));
- }
+ /**
+ * @param valuesToMap list of values to map
+ * @param mappingFunction a function which specifies how to map each element on the list
+ * @return a map created by mapping each element from the {@code valuesToMap} as specified in the {@code mappingFunction}
+ */
+ public static <K, V> Map<K, V> toMap(Collection<V> valuesToMap, Function<V, K> mappingFunction) {
+ return toMap(valuesToMap, mappingFunction, throwingMerger());
+ }
+
+ public static <K, V> Map<K, V> toMap(Collection<V> valuesToMap, Function<V, K> mappingFunction, BinaryOperator<V> mergeFunction) {
+ return streamOfNullable(valuesToMap).collect(Collectors.toMap(mappingFunction, Function.identity(), mergeFunction));
+ }
- /**
- *
- * @param map the map of which it keys to convert
- * @param keyMappingFunction a function which converts the key object
- * @return a map with converted keys.
- */
- public static <K,U, V> Map<U, List<V>> convertMapKeys(Map<K, List<V>> map, Function<K,U> keyMappingFunction) {
- return map.entrySet().stream()
- .collect(Collectors.toMap(entry -> keyMappingFunction.apply(entry.getKey()),
- Map.Entry::getValue));
- }
- /**
- * Create a new hash map and fills it from the given keys and values
- * (keys[index] -> values[index].
- *
- * @param keys
- * The array of keys.
- * @param values
- * The array of values.
- * @return A map that contains for each key element in the keys array a
- * value from the values array at the same index.
- */
- public static <K, V> Map<K, V> newHashMap(K[] keys, V[] values) {
- Map<K, V> map = new HashMap<K, V>();
- if (keys == null || values == null || keys.length != values.length) {
- throw new IllegalArgumentException("keys and values must be non-null and have the same size.");
- }
- for (int i = 0; i < keys.length; i++) {
- map.put(keys[i], values[i]);
- }
- return map;
- }
+ /**
+ * merge two maps. if a key exists in both maps, takes the value from {@code first}
+ *
+ * @param first the first map to merge
+ * @param second the second map to merge
+ * @return the merged map
+ */
+ public static <K, V> Map<K, V> mergeMaps(Map<K, V> first, Map<K, V> second) {
+ if (first == null && second == null) {
+ return new HashMap<>();
+ }
+ if (first != null && second == null) {
+ return new HashMap<>(first);
+ }
+ if (first == null) {
+ return new HashMap<>(second);
+ }
+ Map<K, V> mergedMap = new HashMap<>(first);
+ second.forEach(mergedMap::putIfAbsent);
+ return mergedMap;
+ }
+
+ public static <K, V> List<V> flattenMapValues(Map<K, List<V>> mapToFlatten) {
+ if (mapToFlatten == null) {
+ return new ArrayList<>();
+ }
+ return mapToFlatten.values().stream().flatMap(Collection::stream).collect(toList());
+ }
+
+ /**
+ * @param map the map of which it keys to convert
+ * @param keyMappingFunction a function which converts the key object
+ * @return a map with converted keys.
+ */
+ public static <K, U, V> Map<U, List<V>> convertMapKeys(Map<K, List<V>> map, Function<K, U> keyMappingFunction) {
+ return map.entrySet().stream()
+ .collect(Collectors.toMap(entry -> keyMappingFunction.apply(entry.getKey()),
+ Map.Entry::getValue));
+ }
+
+ /**
+ * Create a new hash map and fills it from the given keys and values
+ * (keys[index] -> values[index].
+ *
+ * @param keys The array of keys.
+ * @param values The array of values.
+ * @return A map that contains for each key element in the keys array a
+ * value from the values array at the same index.
+ */
+ public static <K, V> Map<K, V> newHashMap(K[] keys, V[] values) {
+ Map<K, V> map = new HashMap<>();
+ if (keys == null || values == null || keys.length != values.length) {
+ throw new IllegalArgumentException("keys and values must be non-null and have the same size.");
+ }
+ for (int i = 0; i < keys.length; i++) {
+ map.put(keys[i], values[i]);
+ }
+ return map;
+ }
+
+
+ /**
+ * Returns a merge function, suitable for use in
+ * {@link Map#merge(Object, Object, BiFunction) Map.merge()} or
+ * {@link #toMap(Function, Function, BinaryOperator) toMap()}, which always
+ * throws {@code IllegalStateException}. This can be used to enforce the
+ * assumption that the elements being collected are distinct.
+ *
+ * @param <T> the type of input arguments to the merge function
+ * @return a merge function which always throw {@code IllegalStateException}
+ */
+ private static <T> BinaryOperator<T> throwingMerger() {
+ return (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); };
+ }
+
+ public static <V> Stream<V> streamOfNullable(Collection<V> collection) {
+ return collection == null? Stream.empty(): collection.stream();
+ }
+
+ public static<T> Stream<T> streamOfNullable(T t) {
+ return t == null ? Stream.empty() : Stream.of(t);
+ }
}