Java 如何向ConcurrentHashMap添加空值

Java 如何向ConcurrentHashMap添加空值,java,collections,hashmap,concurrenthashmap,Java,Collections,Hashmap,Concurrenthashmap,我有一个ConcurrentHashMap,它从不同的线程调用,将值放入其中。我必须插入空值,但是ConcurrentHashMap不允许null值。在Java中是否有这样做的方法或替代选项?一个简单的答案是“如果值为null,不要尝试添加它” 另一个答案是从.NET获取一个页面,并引入一个可为空的。您的值将是Nullable的实例 public class Nullable<T> { private final T obj; public Nullable(T t)

我有一个
ConcurrentHashMap
,它从不同的线程调用,将值放入其中。我必须插入空值,但是
ConcurrentHashMap
不允许
null
值。在Java中是否有这样做的方法或替代选项?

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

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

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

    public T get() {
        return obj
    }
}
公共类可为空{
私人终审法院;
公共可空(T){
obj=t;
}
公共部门得不到{
返回obj
}
}
您可以使用null值成功地使实例为null。可以使用get()获取值

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

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

也就是说,您可以使用一个代理对象来表示null。说你的钥匙像钥匙一样。通常,KeyLikeThing具有影响其哈希和equals属性的属性。您可以拥有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);
    }
}
公共类KeyLikeThing{
public static final KeyLikeThing NULL=new KeyLikeThing();
//其他类似钥匙的东西。
}
公共类存储{
私有ConcurrentHashMap m=新ConcurrentHashMap();
公共T put(键式k,T val){
KeyLikeThing kl=k==null?KeyLikeThing.null:k;
返回m.put(kl,val);
}
}

而不是使用无语义且通常被认为是无效的
null
,将此“缺席”概念表示为反映您意图的具体类型,并强制调用方正确解释

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

因此,您的映射将具有一个类型
ConcurrentHashMap


另一个选项是在映射中存储的类型中更直接地表示
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; }
}
然后简单地创建一个
ConcurrentHashMap
。这两种方法都有优缺点,具体取决于您的具体需求,但客观上两者都比在地图中放置
null
值要好



您也可以完全避免添加
null
s-如果您不能为
null
创建一个明确的语义含义,这与简单的缺席不同(如上所述),只需在地图中使用缺席来表达您所关心的,而不是区分缺席和现在,但是-
null
情况。

为什么要这样做?给我们一个用例。你可以使用一个可能重复的对象来代替你的“null”。我改变了这个问题,因为我之前解释的方式有些混乱。我不需要一个键为null,但我希望与我的一些键关联的值为nullnull@gastonmancini它们很相似,但链接的问题实际上是问为什么
Collections.synchronizedMap()
在有
HashMap
支持时不允许空值-回答:是的,海报在测试中犯了错误。我对标题进行了编辑以使其更清晰。我建议使用比
NULL
更清晰的名称,具体取决于您的用例。例如,您可能会对
Person
类型使用
ANONYMOUS
。您的
Nullable
类没有实现
。equals()
,这意味着像
map.containsValue()
这样的操作将被破坏。这是一个演示类。Null不是反模式,请参阅