Equality between 2 HashMap

守給你的承諾、 提交于 2019-12-18 12:48:14

问题


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?


回答1:


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.



回答2:


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.




回答3:


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().




回答4:


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.



来源:https://stackoverflow.com/questions/4082416/equality-between-2-hashmap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!