我有两张地图:
map1 = <K , V>
map2 = <V, someObject>
是否有优雅的&#34;输出结果的方式为:
map3 = <K, someObject>
一种显而易见的方法是迭代map1并执行:
for each entry in map1 {
map3.put(entry.getKey(), map2.get(entry.getValue()))
}
理想情况下,我很欣赏符合Java 7的解决方案;但是使用Java 8的聪明人将有利于教育目的
由于
答案 0 :(得分:3)
这是一个执行此操作的Java 8方法:
public static <K1, K2, V> Map<K1, V> java8Version(Map<K1, K2> first, Map<K2, V> second) {
return first.entrySet()
.stream()
.filter(e -> second.containsKey(e.getValue()))
.collect(Collectors.toMap(Map.Entry::getKey, e -> second.get(e.getValue())));
}
根据需要添加优化和空检查。
这是Java 7版本:
public static <K1, K2, V> Map<K1, V> java7Version(Map<K1, K2> first, Map<K2, V> second) {
HashMap<K1, V> result = new HashMap<>(Math.min(first.size(), second.size()));
for (Map.Entry<K1, K2> entry : first.entrySet()) {
if (second.containsKey(entry.getValue()))
result.put(entry.getKey(), second.get(entry.getValue()));
}
return result;
}
我想我甚至更喜欢Java 7版本,因为它的成本更容易理解和更诚实。
如果您想要保留第一张地图中的密钥,即使它们不在第二张地图中(或者可以选择),请使用以下版本:
public static <K1, K2, V> Map<K1, V> java8VersionWithNulls(Map<K1, K2> first, Map<K2, V> second, boolean keepNulls) {
return first.entrySet()
.stream()
.filter(e -> keepNulls || second.containsKey(e.getValue()))
.collect(Collectors.toMap(Map.Entry::getKey, e -> second.get(e.getValue())));
}
public static <K1, K2, V> Map<K1, V> java7VersionWithNulls(Map<K1, K2> first, Map<K2, V> second, boolean keepNulls) {
HashMap<K1, V> result = new HashMap<>(second.size());
for (Map.Entry<K1, K2> entry : first.entrySet()) {
if (keepNulls || second.containsKey(entry.getValue()))
result.put(entry.getKey(), second.get(entry.getValue()));
}
return result;
}
但我个人并不是说不要这样做。 Null是邪恶的。
以上所有都使用了急切的评价。如果您想要一个反映地图更改的延迟视图,请使用Guava并执行以下操作:
public static <K1, K2, V> Map<K1, V> guavaJava8Version(Map<K1, K2> first, Map<K2, V> second) {
return Maps.transformValues(
Maps.filterKeys(first, Predicates.in(second.keySet())),
second::get);
}
或者,使用静态导入:
public static <K1, K2, V> Map<K1, V> guavaJava8Version(Map<K1, K2> first, Map<K2, V> second) {
return transformValues(filterKeys(first, in(second.keySet())), second::get);
}
由此返回的映射应该对查找和迭代执行得足够好(如果两者都是基于散列的,则为常量时间),但您可能不应该在其上调用size()
(或者它返回的任何集合) )。