【问题标题】:Java hashmaps without the value?没有值的Java hashmaps?
【发布时间】:2010-10-25 17:30:45
【问题描述】:

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

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

谁能帮帮我?

【问题讨论】:

    标签: java hashmap lookup containskey


    【解决方案1】:

    正如大家所说,HashSet 可能是最简单的解决方案,但您不会在 HashSet 中进行恒定时间查找(因为条目可能被链接),并且您将为每个条目存储一个虚拟对象(始终相同)......

    有关信息here a list of data structures,也许您会找到更适合您需求的。

    【讨论】:

      【解决方案2】:

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

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

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

      • 确保对集合的唯一引用位于 final fields 中;
      • 确保确实没有线程修改集合。

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

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

          【解决方案4】:

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

          【讨论】:

            【解决方案5】:

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

            【讨论】:

            • 如果我使用 hashSet 之类的东西,是否意味着我不能使用字符串? hashSet.add("key"); hashSet.contains("key"); //假的,对吧?因为这两个键是单独的对象?
            • jbu,它将使用第一个 hashCode() 然后 equals() 检查成员资格(后者检查冲突)。对于标准库中的对象,比如 String,你的状态很好。如果您定义自己的对象,请确保正确定义了 hashCode() 和 equals()。
            【解决方案6】:

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

            【讨论】:

            • 如果我使用 hashSet 之类的东西,是否意味着我不能使用字符串? hashSet.add("key"); hashSet.contains("key"); //假的,对吧?因为这两个键是单独的对象?
            • 您应该能够很好地使用字符串,因为 String 有自己的 hashCode() 实现,它为相等的字符串返回相同的哈希值。参考:java.sun.com/j2se/1.5.0/docs/api/java/lang/…
            • 如果你想要相同的字符串表示,你也可以查看 intern() 函数
            • 这里没有必要,因为 HashSet 仅基于 hashCode 和 equals,而 String 将始终按预期运行。
            • 注意:HashSet 使用一个 HashMap 和一个虚拟静态对象作为与每个条目关联的值(HashMap 的键)。
            猜你喜欢
            • 2011-04-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-10-20
            • 1970-01-01
            • 2013-02-12
            • 1970-01-01
            • 2013-07-09
            相关资源
            最近更新 更多