【问题标题】:Custom object as a key in HashMap自定义对象作为 HashMap 中的键
【发布时间】:2020-09-11 04:46:21
【问题描述】:

众所周知,我们可以使用任何 Object 作为 Java HashMap 中的键,只要它遵循 equals 和 hashCode 协定。 但是我在某处读过它——如果自定义对象是不可变的,那么这已经被处理了。 这是否意味着如果我的自定义对象是不可变的,我不需要重写 hashcode 和 equals 方法以使其有资格将其用作我的 hashmap 的键。

我的理解是这是错误的,即使我的自定义对象是不可变的,它也必须重写 hashcode 和 equals 方法才能使其符合 hashmap 键的条件。 如果你们有不同的看法,请发表评论。

【问题讨论】:

  • 你能澄清一下在java对象中实现不可变是什么意思吗?你可以让java对象只有构造函数+getter而没有setter,你可以调用不可变的。如果是这种情况,你仍然需要有equal和hashcode
  • 是的,Chayne,完全按照您描述的方式实现不可变类。因此,根据您的说法,我们仍然需要覆盖 hashcode 和 equals 方法,以使我的地图条目插入和搜索正确。

标签: java


【解决方案1】:

构造地图不会有问题,而且你的每一个条目,除非对象的哈希码碰撞将是唯一的。但是基于键的搜索将是一个问题。由于它是不可变的,因此您确实无法创建可以匹配映射中的键的键。

{
        HashMap<ImmutableKey, String> map = new HashMap<>();
        ImmutableKey key = new ImmutableKey("A", "B");
        map.put(key, "Test");
        map.put(new ImmutableKey("A", "B"), "Test1");
        map.put(new ImmutableKey("A", "B"), "Test2");
        map.put(new ImmutableKey("A", "B"), "Test3");

        System.out.println(map);
        String data = map.get(new ImmutableKey("A", "B"));
        System.out.println(data);

}

final class ImmutableKey {
    private String key;
    private String value;

    public ImmutableKey(String key, String value) {
        this.key = key;
        this.value = value;
    }

    public String getKey() {
        return key;
    }

    public String getValue() {
        return value;
    }
}

【讨论】:

    【解决方案2】:

    不变性意味着几件事,但在其最基本的形式中,对象一旦创建就无法更改。这在哈希查找中可能很有用,但您可能想到的是持久性,这是一个相关但独立的概念,其中对对象的更改返回一个新对象而不是更改现有对象(写入时复制语义)。

    但是,要了解为什么不可变性或持久性都有助于哈希查找,需要了解如何实现基本哈希码和相等方法。幸运的是,这些实现通常相当简单:只需返回 object’s position in memory。这通常不能很好地工作,因为即使类中的数据完全相同,一个类的两个实例在内存中也会有两个不同的位置。如果要对没有setter的类进行hash,一般还是需要根据成员计算相等性和hash。

    使用持久性,这可能很有用,因为持久性数据结构(例如hash array mapped trie)通常会为两个不同构造的结构返回相同的对象,例如set("a").add("b").id == set("a", "b").id。随后,持久数据结构可以有效地使用 ID 进行散列和相等性。

    因此,要回答您最初的问题,您应该在没有设置器的情况下在您的班级上实现 hashCodeequals :-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-10
      • 1970-01-01
      • 1970-01-01
      • 2019-09-13
      • 2011-11-08
      • 1970-01-01
      相关资源
      最近更新 更多