2个HashMap之间相等

发布于 2024-09-30 04:49:13 字数 300 浏览 0 评论 0原文

在我的类的 equals() 方法中,我使用私有实例 HashMap 变量来比较相等性。然而,在比较 HashMap 变量时,两个不同的对象仍然显示相等。进一步的研究将我带到了链接:链接此处。然而,它只是说 HashMap1.equals(HashMap2) 不起作用的原因是“显然,如果不编写自定义代码,就无法测试 Java 数组的相等性”。

我不明白这个原因。谁能指导我详细的原因吗?

In the equals() method of my class, I am using a private instance HashMap variable to compare for the equality. However, 2 different objects still show being equal when comparing their HashMap variables. Further research brought me to the link : Link Here . However, it just says that the reason for HashMap1.equals(HashMap2) not working is because " apparantly Java's arrays cannot be tested for equality without writing a customized code."

I did not understand this reason. Can anyone please guide me to a elaborate reason?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

谜兔 2024-10-07 04:49:13

Java 数组类型上的 equals 方法相当于 ==,因为 Java 数组“类”不会覆盖 Object.equals

如果您想“按值”比较数组,您需要使用适当的 java.util.Arrays.equals(...) 方法,或者自己实现它。

如果您的 HashMap 使用数组作为键或值,那么它将调用数组的 equals 方法来测试两个映射之间的键和/或值是否相同。这会让 HashMap.equals 表现得很奇怪(从你的角度来看)。这就是链接文章所说的内容。但是,如果您使用数组作为键或值类,则数组语义会影响HashMap 相等性。如果不这样做,那么 HashMap::equals 应该按预期工作。

Map 类上的相等性 javadoc 有点复杂,但它们基本上归结为获取两个条目集,比较它们的大小,然后执行 s1.containsAll(s2)。当然,这很昂贵,但它应该适用于所有正确实现Map接口的Map类。


请注意,使用数组作为映射的键不是一个好主意,原因如下:

  1. 数组 equalshashCode 的语义对于 HashMap 是错误的> 在大多数情况下。对于大多数用例,您需要映射按值而不是按对象标识来比较键。
  2. 数组是可变的。如果我们假设有解决equals / hashcode问题的方法,您仍然可以通过修改数组键来破坏映射的不变量。

The equals method on a Java array type is equivalent to ==, because Java array "classes" do not override Object.equals.

If you want to compare arrays "by value" you need to either use the appropriate java.util.Arrays.equals(...) method, or implement it yourself.

If your HashMap uses arrays as keys or values, then it is going to call the array's equals method to test if the keys and/or values are the same between two maps. This would make HashMap.equals behave strangely (from your perspective). That is what the linked article is saying. However, array semantic only affect HashMap equality if you use arrays as the key or value classes. If you don't, then HashMap::equals should just work as expected.

The javadocs for equality on Map classes are a bit involved, but they basically boil down to taking the two entry sets, comparing their sizes, and then doing s1.containsAll(s2). Of course, this is expensive, but it should work for all of the Map classes that correctly implement the Map interface.


Note that using arrays as keys for maps is a bad idea for a couple of reasons:

  1. The semantics of array equals and hashCode are wrong for a HashMap in most scenarios. For most use-cases, you need the map to compare the keys by value not by object identity.
  2. Arrays are mutable. If we assumed that there was a workaround for the equals / hashcode problem, you could still break a map's invariants by modifying an array key.
贱贱哒 2024-10-07 04:49:13

文章是对的。只要可以使用相同的方法比较键对象和值对象,就可以使用 equals() 方法安全地比较哈希图。在本文中,映射值是数组,它没有按预期实现 equals()。使用 ArrayList 可以解决这个问题。

The article is right. Hashmaps can be safely compared using the equals() method as long as the key objects and value objects are possible to compare using the same method. In the article, the map values are arrays, which do not implement equals() as expected. Using ArrayList instead would have solved the problem.

舂唻埖巳落 2024-10-07 04:49:13

本机 Java 数组没有 .equals() 函数。因此,如果您的哈希图的值(或我认为的键)是数组,则 HashMap.equals() 将失败。我怀疑它会依赖于 Object.equals() ,它只是检查两个对象是否实际上是同一个对象。

// something like this
class Object {
  public boolean equals( Object o) {
    return this == o;
  }
}

您可以通过在 Container 上使用某些变体而不是 array[] 来回避问题,因为容器有自己的 .equals() ,它对容器的连续元素调用 equals() 而不是简单地检查它们是否是相同的引用。 Collection.equals 实现的代码可能类似于:

public boolean equals(Object o) {
  // sets never equal lists and visa versa
  if (o instanceof MyCollectionSubclass) {
    Iterator myIterator = iterator();
    Iterator theirIterator = ((Collection)o).iterator();
    while (myIterator.hasNext() && theirIterator.hasNext()) {
      Object myObj = myIterator.next();
      Object theirObj = theirIterator.next();
      if (!myObj.equals(theirObj)) {
        return false;
      }
    }
    // at least one will be false or we wouldn't have left the above while loop
    return myIterator.hasNext() == theirIterator.hasNext();
  }
  // not our class
  return false;
}

这可能会产生真实值比较,具体取决于调用集合内容的 equals() 时的操作。

Native Java arrays don't have a .equals() function. So if your hashmap's values (or keys I suppose) are arrays, HashMap.equals() will fail. I suspect it'd fall back on Object.equals() which just checks to see if the two objects are actually the same object.

// something like this
class Object {
  public boolean equals( Object o) {
    return this == o;
  }
}

You can sidestep the problem by using some variant on a Container rather than an array[], as containers have their own .equals() which calls equals() on successive elements of the containers rather than simply checking if they're the same reference. The code for a Collection.equals implementation might look something like:

public boolean equals(Object o) {
  // sets never equal lists and visa versa
  if (o instanceof MyCollectionSubclass) {
    Iterator myIterator = iterator();
    Iterator theirIterator = ((Collection)o).iterator();
    while (myIterator.hasNext() && theirIterator.hasNext()) {
      Object myObj = myIterator.next();
      Object theirObj = theirIterator.next();
      if (!myObj.equals(theirObj)) {
        return false;
      }
    }
    // at least one will be false or we wouldn't have left the above while loop
    return myIterator.hasNext() == theirIterator.hasNext();
  }
  // not our class
  return false;
}

This might produce a true value comparison depending on what the collection's contents do when you call their equals().

风苍溪 2024-10-07 04:49:13

如果不编写自定义代码,就无法测试 Java 数组的相等性

这只是一种复杂的说法,表明 Java 数组不会重写 Object.equals()。因此,如果您使用 equals() 来比较它们(这是所有集合类的 equals 方法所做的),您会得到“实例相等”,而不是“值相等” ”。

这实际上只是 equals 工作的不同方式的一个特例,具体取决于它是否被覆盖。

Java's arrays cannot be tested for equality without writing a customized code

This is just a complicated way of saying that Java arrays do not override Object.equals(). Hence if you compare them using equals() (which is what the equals methods of all the collection classes do), you get "instance equality", instead of "value equality".

That's really just a special case of the different ways equals works depending on whether it has been overridden or not.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文