【问题标题】:Any disadvantage to using arbitrary objects as Map keys in Java?在 Java 中使用任意对象作为 Map 键有什么缺点吗?
【发布时间】:2009-03-11 15:21:03
【问题描述】:

我的应用程序中有两种对象,其中一种对象恰好有一个对应的另一种对象。

跟踪这种关系的明显选择是Map<type1, type2>,就像一个HashMap。但不知何故,我很怀疑。我可以在 Map 中使用一个对象作为键,传递它,让它也放在另一个集合中,并随时从 Map 中检索它的伙伴吗?

创建对象后,我传递的只是一个标识符,对吧?所以那里可能没有问题。如果我序列化和反序列化密钥会怎样?

还有其他注意事项吗?我是否应该使用其他东西来关联对象对,例如我自己生成的数字?

【问题讨论】:

    标签: java collections maps


    【解决方案1】:
    1. key需要正确实现.equals().hashCode()
    2. 不得在用作键时以任何方式更改其 .hashCode()
    3. 理想情况下,在HashMap 中用作键的任何对象都应该是不可变的。这将自动确保 2. 始终为真。
    4. 可能会被 GC 处理的对象在用作键和/或值时可能会被保留。

    【讨论】:

      【解决方案2】:

      我有两种对象 一个应用程序的每个对象 kind 有一个对应的 其他类型的对象。

      这听起来确实像一个有关系,因此可以使用一个简单的属性来实现。

      【讨论】:

      • 我同意。不过,问题的其余部分可能对其他人仍然有用。 (或者甚至对于@OP,如果出于某种原因这不是替代方案)
      • @saua 我同意你的看法。我只是想指出属性在这个特定上下文中的适用性。
      【解决方案3】:

      这取决于你选择的地图的实现:

      • HashMap 使用 equals()hashCode()。默认情况下(在对象中),这些基于对象标识,除非您序列化/反序列化,否则它将正常工作。根据对象的内容正确实现 equals() 和 hashCode() 不会有任何问题,只要在它是哈希映射中的键时不对其进行修改。

        李>
      • TreeMap 使用 compareTo()。没有默认实现,因此您需要提供一个。与上面实现 hashCode() 和 equals() 的限制相同。

      【讨论】:

        【解决方案4】:

        您可以使用标准 Map,但这样做会在 Map 中保留对对象的强引用。如果您的对象在另一个结构中被引用,并且您只需要 Map 将它们链接在一起,请考虑使用 Wea​​kHashMap。

        顺便说一句,除非您必须将对象的多个实例视为相等,否则您不必重写 equals 和 hashCode...

        【讨论】:

          【解决方案5】:

          我可以在 Map 中使用一个对象作为键,传递它,让它也放在另一个集合中,并随时从 Map 中检索它的伙伴吗?

          是的,这里完全没有问题。

          创建对象后,我传递的只是一个标识符,对吧?所以那里可能没有问题。如果我序列化和反序列化密钥会怎样?

          没错,你只是在传递一个引用——它们都会指向同一个实际对象。如果您序列化或反序列化对象,则会创建一个新对象。但是,如果您的对象正确实现了 equals 和 hashCode,您应该仍然能够使用新的反序列化对象从地图中检索项目。

          还有其他注意事项吗?我是否应该使用其他东西来关联对象对,例如我自己生成的数字?

          至于注意事项,是的,当对象在 Map 中时,您不能更改任何会导致对象的 hashCode 更改的内容。

          【讨论】:

            【解决方案6】:

            任何对象都可以是映射键。这里重要的是确保为将用作映射键的任何对象覆盖 .equals() 和 .hashCode()。

            您这样做的原因是,如果您不这样做,equals 将被理解为对象相等,并且您能够找到“相等”映射键的唯一方法是拥有原始对象本身的句柄.

            您覆盖哈希码是因为它需要与 equals 一致。这是为了让您定义为 equals 的对象具有相同的哈希值。

            【讨论】:

              【解决方案7】:

              失败点是 hashcode 和 equals 函数。如果它们不能产生一致且正确的返回值,则 Map 的行为会很奇怪。 Effective Java 有一个完整的部分,强烈推荐。

              【讨论】:

                【解决方案8】:

                您可以考虑使用 Google 收藏集的BiMap

                【讨论】:

                  猜你喜欢
                  • 2022-06-14
                  • 1970-01-01
                  • 2018-09-01
                  • 2010-11-25
                  • 2016-03-30
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-12-15
                  相关资源
                  最近更新 更多