没有值的Java哈希映射?

jbu*_*jbu 25 java lookup hashmap containskey

假设我想在数据结构中添加单词,并且我希望有恒定时间查找以查看该单词是否在此数据结构中.我想做的就是看看这个词是否存在.我会使用HashMap(containsKey())吗? HashMap使用key->值配对,但在我的情况下,我没有值.当然我可以使用null作为值,但即使null也需要空格.看起来这个应用程序应该有更好的数据结构.

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

谁能帮我吗?

Dan*_*Lew 46

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

  • 你应该可以正常使用Strings,因为String有自己的hashCode()实现,它为相同的字符串返回相同的哈希值.参考:http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html#hashCode() (5认同)
  • 注意:HashSet使用HashMap和虚拟静态Object作为与每个条目(HashMap的键)关联的值. (3认同)
  • 这里不必要,因为HashSets完全基于hashCode和equals,而String总是按照预期的那样运行. (2认同)

Nam*_*ter 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.


Nei*_*fey 7

您通常使用Set的实现,通常使用HashSet.如果确实需要并发访问,那么ConcurrentHashSet提供了一个直接替换,它提供安全的并发访问,包括对集合的安全迭代.

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

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

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

您可以使用Collections.unmodifiableSet()包装器来帮助确保后者.这给你一个给定集合的不可修改的视图 - 因此没有提供对集合转义的其他"正常"引用,你是安全的.


小智 6

您希望使用实现Set接口的Collection,可能使用HashSet来获得您声明的性能.请参阅http://java.sun.com/javase/6/docs/api/java/util/Set.html