org.apache.karaf.features.internal.util.MapUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.apache.karaf.features.core Show documentation
Show all versions of org.apache.karaf.features.core Show documentation
This bundle is the core implementation of the Karaf features support.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.karaf.features.internal.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import static java.util.stream.Collectors.toSet;
public final class MapUtils {
private MapUtils() {
}
public static Map> invert(Map map) {
Map> inverted = new HashMap<>(map.size());
for (Map.Entry entry : map.entrySet()) {
addToMapSet(inverted, entry.getValue(), entry.getKey());
}
return inverted;
}
/**
* Changes mapping from S
-> Set<T>
to mapping
* S
-> Set<U>
using {@link Function} that can change T
to
* U
.
*
* @param mapset
* @param function
* @param A key that maps to set of values in input and result map
* @param A type of input set of values
* @param A type of result set of values
* @return
*/
public static Map> apply(Map> mapset, Function function) {
Map> result = new HashMap<>(mapset.size());
for (Map.Entry> entry : mapset.entrySet()) {
result.put(entry.getKey(), apply(entry.getValue(), function));
}
return result;
}
public static Set apply(Set set, Function function) {
Set result = new HashSet<>(set.size());
for (T t : set) {
U u = function.apply(t);
if (u != null) {
result.add(u);
}
}
return result;
}
public static Map build(Collection col, Function key, Function value) {
Map result = new HashMap<>(col.size());
for (S s : col) {
T t = key.apply(s);
U u = value.apply(s);
if (t != null && u != null) {
result.put(t, u);
}
}
return result;
}
public static Function compose(final Function f1, final Function f2) {
return s -> f2.apply(f1.apply(s));
}
public static Function map(final Map map) {
return map::get;
}
public static boolean contains(Map> mapset, S key, T val) {
Set set = mapset.get(key);
return set != null && set.contains(val);
}
public static Set flatten(Map> mapset) {
Set set = new HashSet<>();
for (Set s : mapset.values()) {
set.addAll(s);
}
return set;
}
/**
* Produces a map where each set value in from
map has every element that's in to
* map's set value removed. If from
map is left with empty set value, entire set is removed.
* @param from
* @param to
* @param
* @param
* @return
*/
public static Map> diff(Map> from, Map> to) {
Map> diff = copyMapSet(from);
remove(diff, to);
return diff;
}
public static void add(Map> from, Map> toAdd) {
for (Map.Entry> entry : toAdd.entrySet()) {
from.computeIfAbsent(entry.getKey(), k -> new HashSet<>()).addAll(entry.getValue());
}
}
public static void retain(Map> from, Map> toRetain) {
for (Iterator>> iterator = from.entrySet().iterator(); iterator.hasNext();) {
Map.Entry> entry = iterator.next();
Set s = toRetain.get(entry.getKey());
if (s != null) {
entry.getValue().retainAll(s);
} else {
iterator.remove();
}
}
}
/**
* Removes all values from toRemove
map from from
map. After removal, set values
* in from
map may be smaller or removed entirely (if there are no more values in given set).
* @param from
* @param toRemove
* @param
* @param
*/
public static void remove(Map> from, Map> toRemove) {
for (Map.Entry> entry : toRemove.entrySet()) {
Set s = from.get(entry.getKey());
if (s != null) {
s.removeAll(entry.getValue());
if (s.isEmpty()) {
from.remove(entry.getKey());
}
}
}
}
@SuppressWarnings({
"unchecked", "rawtypes"
})
public static S copy(S obj) {
if (obj instanceof List) {
List r = new ArrayList();
for (Object o : (List) obj) {
r.add(copy(o));
}
return (S) r;
} else if (obj instanceof Set) {
Set r = new HashSet();
for (Object o : (Set) obj) {
r.add(copy(o));
}
return (S) r;
} else if (obj instanceof Map) {
Map r = new HashMap();
for (Map.Entry e : ((Map) obj).entrySet()) {
r.put(copy(e.getKey()), copy(e.getValue()));
}
return (S) r;
}
return obj;
}
@SuppressWarnings({
"rawtypes", "unchecked"
})
public static void copy(S s1, S s2) {
if (s1 instanceof Collection) {
for (Object o : (Collection) s1) {
((Collection) s2).add(copy(o));
}
} else if (s1 instanceof Map) {
for (Map.Entry e : ((Map) s1).entrySet()) {
((Map) s2).put(copy(e.getKey()), copy(e.getValue()));
}
} else {
throw new IllegalArgumentException("Source is not a Collection or a Map");
}
}
public static Map> copyMapSet(Map> from) {
Map> to = new HashMap<>();
copyMapSet(from, to);
return to;
}
public static void copyMapSet(Map> from, Map> to) {
for (Map.Entry> entry : from.entrySet()) {
to.put(entry.getKey(), new HashSet<>(entry.getValue()));
}
}
public static void addToMapSet(Map> map, S key, T value) {
map.computeIfAbsent(key, k -> new HashSet<>()).add(value);
}
public static void removeFromMapSet(Map> map, S key, T value) {
Set values = map.get(key);
if (values != null) {
values.remove(value);
if (values.isEmpty()) {
map.remove(key);
}
}
}
public static Set diff(Set s1, Set s2) {
Set s = new HashSet<>(s1);
s.removeAll(s2);
return s;
}
public static Set map(Set s, Function mapper) {
return s.stream().map(mapper).collect(toSet());
}
public static Set filter(Set s, Predicate predicate) {
return s.stream().filter(predicate).collect(toSet());
}
}