使用Key为1的Java哈希映射作为other的值

时间:2016-05-30 16:27:38

标签: java hashmap

我有两张地图:

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的聪明人将有利于教育目的

由于

1 个答案:

答案 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()(或者它返回的任何集合) )。