如何将空值添加到ConcurrentHashMap

Kha*_*Ali 3 java collections hashmap concurrenthashmap

我有一个ConcurrentHashMap从不同的线程调用,以将值放入其中.我必须插入空值,但ConcurrentHashMap不允许null值.有没有办法在Java中执行此操作或替代选项?

dim*_*414 5

而不是使用null没有语义含义并且通常被认为是反模式的,而不是将这种"缺席"概念表示为反映您的意图并迫使呼叫者正确解释它的具体类型.

一个常见的解决方案是使用Optional(对于Java 8之前的版本,使用Guava Optional)来表示缺少值.

所以你的地图会有一个类型ConcurrentHashMap<Key, Optional<Value>>.


另一种选择是通过null更直接地在地图中存储的类型来表示您想要表达的任何内容,例如,如果null应该表示"这曾经存在,但不再存在",您可能会创建类似这样的类结构:

public abstract class Resource {
  public abstract void doSomething();
  public abstract ClosedResource close();
}

public class ActiveResource extends Resource {
  public void doSomething() { ... }
  public ClosedResource close() { ... }
}

public class ClosedResource extends Resource {
  public void doSomething() { /* nothing to do */ }
  public ClosedResource close() { return this; }
}
Run Code Online (Sandbox Code Playgroud)

然后简单地说ConcurrentHashMap<Key, Resource>.根据您的确切需求,这两种方法都有利有弊,但两者都比null在地图中放置值更客观.


你也可以简单地避免添加nulls - 如果你不能创建一个明确的语义含义,null那就不同于简单地缺席(如上所述),只需在地图中使用缺席来表达你关心的内容,而不是而不是区分缺席和现在但是null案件.

  • Null 不是反模式,请参阅 https://medium.com/@elizarov/null-is-your-friend-not-a-mistake-b63ff1751dd5 (2认同)

Vir*_*ndi 3

一个简单的答案是“如果该值为空,则不要尝试添加它”。

另一个答案是从 .NET 中获取页面并引入 Nullable。您的值将是 Nullable 的一个实例。

public class Nullable<T> {
    private final T obj;
    public Nullable(T t) {
        obj = t;
    }

    public T get() {
        return obj
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以成功地创建具有 null 值的 Nullable 实例。您可以使用 get() 获取该值。

--- 这是旧版本的答案 ---

首先,为什么需要放置一个空键?这似乎是您设计中的一个问题。

话虽这么说,您可以使用 null 的替代对象。假设您的密钥是 KeyLikeThing。通常,KeyLikeThing 具有影响其哈希和等于属性的属性。您可以在您的世界中拥有一个 KeyLikeThing 的实例为 null 的实例。当您的客户端想要输入 null 时,它会使用 KeyLikeThing 的实例。

public class KeyLikeThing {
    public static final KeyLikeThing NULL = new KeyLikeThing();

    // Other KeyLikeThing related stuff.
}

public class Storage<T> {
    private ConcurrentHashMap m = new ConcurrentHashMap();

    public T put(KeyLikeThing k, T val) {
        KeyLikeThing kl = k == null ? KeyLikeThing.NULL : k;
        return m.put(kl, val);
    }
}
Run Code Online (Sandbox Code Playgroud)