为什么ConcurrentHashMap,HashTable不支持key,value为null?

2 个回答

  • 苏青衣
    谎言不会伤人,真相才是快刀。
    ### 1. **线程安全和原子性问题** 在多线程环境下,`ConcurrentHashMap` 和 `HashTable` 需要确保线程安全。如果允许 `key` 或 `value` 为 `null`,在某些情况下,`null` 可能会引起歧义和错误处理。例如: - **`get(key)` 与 `containsKey(key)` 的组合操作**: - 如果 `ConcurrentHashMap` 或 `HashTable` 支持 `null` 值,那么在多线程环境中,当一个线程调用 `containsKey(key)` 判断一个 `key` 是否存在时,另一个线程可能在这个判断之后但在 `get(key)` 之前删除了该键值对。此时,`get(key)` 返回 `null`,但调用者无法确定这个 `null` 是因为 `key` 不存在,还是因为 `key` 的 `value` 为 `null`。这种不确定性可能导致逻辑错误和异常。 ### 2. **设计意图** - **明确性和简化设计**: - 设计者为了避免上面提到的歧义问题,明确规定 `ConcurrentHashMap` 和 `HashTable` 不允许 `null` 作为 `key` 或 `value`。这简化了实现逻辑,并且避免了在多线程环境下可能出现的一系列复杂问题。 - **增强 API 的安全性**: - 不允许 `null` 作为 `key` 或 `value` 可以减少开发人员在使用这些集合类时可能犯的错误,因为在不支持 `null` 的情况下,任何尝试插入或查询 `null` 的操作都会立即抛出异常,提醒开发者检查代码逻辑,而不是在运行时引发难以调试的逻辑错误。 ### 3. **与 HashMap 的对比** - **HashMap 是非线程安全的**: - 在单线程环境中使用 `HashMap` 时,如果 `get(key)` 返回 `null`,开发者可以通过 `containsKey(key)` 来判断 `key` 是否存在,以及 `null` 是否表示 `value` 为 `null`。然而,这种操作在多线程环境下可能不是安全的。 - **在单线程环境下的灵活性**: - 由于 `HashMap` 主要设计用于非并发环境,它允许 `key` 和 `value` 为 `null`,以提供更大的灵活性。 ### 4. **总结** 综上所述,`ConcurrentHashMap` 和 `HashTable` 不支持 `key` 和 `value` 为 `null` 是出于线程安全和设计简化的考虑。通过禁止 `null`,这些类可以更容易地避免在多线程环境中可能发生的逻辑错误和不确定性,同时也提供了更加安全和明确的 API。
    发布于 2022-07-13 23:17 •IP属地 江苏
    举报
    评论
    收藏

  • 松林
    入体冰凉的月光,都比不上你绝情的目光。
    因为HashMap是非线程安全的,默认单线程环境中使用,如果get(key)为null,可以通过containsKey(key) 方法来判断这个key的value为null,还是不存在这个key,而ConcurrentHashMap,HashTable是线程安全的, 在多线程操作时,因为get(key)和containsKey(key)两个操作和在一起不是一个原子性操作,可能在containsKey(key)时发现存在这个键值对,但是get(key)时,有其他线程删除了键值对,导致get(key)返回的Node是null,然后执行方法时抛出异常。所以无法区分value为null还是不存在key。 至于ConcurrentHashMap,HashTable的key不能为null,主要是设计者的设计意图。
    发布于 2022-01-19 18:54 •IP属地 云南
    举报
    评论
    收藏