HashMap返回未找到键的默认值?

Lar*_*rry 136 java dictionary hashmap

是否可以为HashMap集合中找不到的所有键返回默认值?

Spy*_*cho 157

在Java 8中,使用Map.getOrDefault.它接受密钥,如果找不到匹配的密钥则返回值.

  • `getOrDefault`非常好,但每次访问地图时都需要默认定义.在创建静态值映射时,定义一次默认值也具有可读性优势. (12认同)
  • 这对于实现自己来说是微不足道的.`private static String get(Map map,String s){return map.getOrDefault(s,"Error"); }` (3认同)

mae*_*ics 120

[更新]

正如其他答案和评论者所指出的,从Java 8开始,您可以简单地调用Map#getOrDefault(...).

[原版的]

没有Map实现可以完全做到这一点,但通过扩展HashMap实现自己的实现是微不足道的:

public class DefaultHashMap<K,V> extends HashMap<K,V> {
  protected V defaultValue;
  public DefaultHashMap(V defaultValue) {
    this.defaultValue = defaultValue;
  }
  @Override
  public V get(Object k) {
    return containsKey(k) ? super.get(k) : defaultValue;
  }
}
Run Code Online (Sandbox Code Playgroud)

  • _在General_中,我认为这是一个坏主意 - 我会将默认行为推送到客户端,或者一个不声称是地图的代表.特别是,缺少有效的keySet()或entrySet()将导致任何需要遵守Map合约的问题.包含Key()暗示的无限有效键集可能会导致难以诊断的糟糕性能.但不是说,它可能不会用于某种特定目的. (21认同)
  • 准确地说,你可能想要将条件从`(v == null)`调整到`(v == null &&!this.containsKey(k))`以防它们故意添加一个'null`值.我知道,这只是一个极端的案例,但作者可能会遇到它. (19认同)

Dav*_*ton 72

如果您不想重新发明轮子,请使用Commons的DefaultedMap,例如,

Map<String, String> map = new DefaultedMap<>("[NO ENTRY FOUND]");
String surname = map.get("Surname"); 
// surname == "[NO ENTRY FOUND]"
Run Code Online (Sandbox Code Playgroud)

如果您不首先负责创建地图,也可以传入现有地图.

  • +1尽管有时它更容易重新发明轮子而不是为简单功能的微小片段引入大的依赖性. (26认同)
  • 有趣的是,我使用的很多项目在classpath中都有类似的东西(Apache Commons或Google Guava) (2认同)

Vad*_*zim 44

Java 8 为接口引入了一个很好的computeIfAbsent默认方法,Map它存储了延迟计算的值,因此不会破坏map合约:

Map<Key, Graph> map = new HashMap<>();
map.computeIfAbsent(aKey, key -> createExpensiveGraph(key));
Run Code Online (Sandbox Code Playgroud)

来源:http://blog.javabien.net/2014/02/20/loadingcache-in-java-8-without-guava/

免责声明: 这个答案与OP所要求的不完全匹配,但在某些情况下,当密钥数量有限并且不同值的缓存有利时,可能会在某些情况下匹配问题标题.它不应该在相反的情况下使用大量的键和相同的默认值,因为这将不必要地浪费内存.


She*_*ari 12

难道你不能只创建一个这样做的静态方法吗?

private static <K, V> V getOrDefault(Map<K,V> map, K key, V defaultValue) {
    return map.containsKey(key) ? map.get(key) : defaultValue;
}
Run Code Online (Sandbox Code Playgroud)


Iva*_*tyk 10

您可以简单地创建一个继承HashMap并添加getDefault方法的新类.这是一个示例代码:

public class DefaultHashMap<K,V> extends HashMap<K,V> {
    public V getDefault(K key, V defaultValue) {
        if (containsKey(key)) {
            return get(key);
        }

        return defaultValue;
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为你不应该在你的实现中覆盖get(K key)方法,因为Ed Staub在他的评论中指定的原因以及你将破坏Map接口的合同(这可能会导致一些难以找到的错误).

  • 你有一点不重写`get`方法.另一方面 - 您的解决方案不允许通过接口使用类,这可能经常是这种情况. (4认同)

Die*_*vis 5

使用:

myHashMap.getOrDefault(key, defaultValue);
Run Code Online (Sandbox Code Playgroud)


Edu*_*rdo 5

在 Java 8+

Map.getOrDefault(Object key,V defaultValue)
Run Code Online (Sandbox Code Playgroud)