31

假设我想将单词放入数据结构中,并且我想进行持续时间查找以查看单词是否在此数据结构中。我只想看看这个词是否存在。我会为此使用HashMap(containsKey()) 吗? HashMaps 使用键-> 值配对,但在我的情况下,我没有值。当然我可以使用 null 作为值,但即使是 null 也会占用空间。似乎这个应用程序应该有一个更好的数据结构。

该集合可能被多个线程使用,但由于集合包含的对象不会改变,我认为我没有同步/并发要求。

谁能帮我吗?

4

6 回答 6

51

请改用HashSet它是Set的哈希实现,主要用于您所描述的内容(无序的项目集)。

于 2009-05-13T00:57:32.160 回答
8

您通常会使用Set的实现,最常见的是 HashSet。如果您确实需要并发访问,那么 ConcurrentHashSet 提供了一个插入式替换,它提供了安全的并发访问,包括对集合的安全迭代。

在任何情况下,我都建议在您的代码中将其简单地称为 Set ,除非在您构造它的地方;这样,如果您以后需要它,就更容易为另一个实现添加一个实现。

即使该集合是只读的,如果它被创建它的线程以外的线程使用,您确实需要考虑安全发布(即确保任何其他线程看到该集合处于一致状态:记住任何内存写入,即使在构造函数中,也不能保证在您期望的时间或其他线程中可供其他线程使用,除非您采取措施确保这一点)。这可以通过以下两种方式完成:

  • 确保对集合的唯一引用位于最终字段中;
  • 确保确实没有线程修改集合。

您可以通过使用 Collections.unmodifiableSet() 包装器来帮助确保后者。这为您提供了给定集合的不可修改视图 - 因此,如果没有其他“正常”引用集合转义,您是安全的。

于 2009-05-13T01:36:08.403 回答
7

您可能想使用java.util.Set。实现包括java.util.HashSet,它是 HashMap 的 Set 等价物。

即使集合中包含的对象没有变化,您也可能需要进行同步。将 Set 传递给不同的线程后,是否需要将新对象添加到 Set 中?如果是这样,您可以使用Collections.synchronizedSet()使 Set 线程安全。

如果您有一个带有值的 Map,并且您有一些代码只想将 Map 视为一个 Set,您可以使用 Map.entrySet()(但请记住,entrySet 返回 Map 中键的 Set 视图;如果 Map 是可变的,则可以通过 entrySet 返回的集合来改变 Map)。

于 2009-05-13T01:05:47.927 回答
6

您想使用实现 Set 接口的 Collection ,可能是 HashSet 来获得您所说的性能。见http://java.sun.com/javase/6/docs/api/java/util/Set.html

于 2009-05-13T00:58:40.083 回答
1

除了Sets,在某些情况下,您可能希望将 aMap转换为Setwith Collections.newSetFromMap(Map<E,Boolean>)(一些Maps 不允许null值,因此是Boolean)。

于 2009-05-13T01:02:36.717 回答
-1

as everyone said HashSet is probably the simplest solution but you won't have constant time lookup in a HashSet (because entries may be chained) and you will store a dummy object (always the same) for every entry...

For information here a list of data structures maybe you'll find one that better fits your needs.

于 2009-05-13T11:47:36.887 回答