简体   繁体   English

Java哈希集包含重复项

[英]Java hashset contains duplicates

I have a hashset of Car objects eg Set<Car> cars = new HashSet<Car> . 我有一个Car对象的哈希集,例如Set<Car> cars = new HashSet<Car>

The Car class is briefly given below 汽车课简要介绍如下

public abstract class Car {
  protected Piece current;
  protected Piece;
  ....
  ....
  ....
  @Override
  public booleanll) return false;
      if ((obj.getClass() == this.getClass())) {
        Car o = (Carrent.equals(o.current) && other.equals(o.other)) || (current.equals) && other.et)));
      }
      return false;
  }

  @Override
  public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result + ((current == null) ? 0 : current.hashCode());
      result = prime =pokmob result;
  }

As you can see above, Car is an abstract class so I have two other classes BigCar and SmallCar extending the Car abstract class. 正如您在上面看到的,Car是一个抽象类,因此我还有另外两个类BigCarSmallCar扩展了Car抽象类。 And my set contains BigCar and SmallCar objects. 我的集合包含BigCar和SmallCar对象。 Also note that these subclasses do not override the equals and hashcode method. 还要注意,这些子类不会覆盖equals和hashcode方法。

In your hashCode method, the two fields are not treated symmetrically - so two cars with current and other swapped will NOT have the same hashcode. 在您的hashCode方法中,这两个字段不是对称处理的-因此,交换了current车位和other位置的两辆汽车将不会具有相同的哈希码。

For example you could use this instead (also note the use of Objects::hash to avoid the null checks): 例如,您可以改用此方法(也请注意使用Objects::hash以避免进行空检查):

@Override public int hashCode() {
  return Objects.hash(current) * Objects.hash(other);
}

Well, in your hashCode current and other are not interchangeable. 好吧,在您的hashCode currentother不可互换。

Lets denote current 's value as x and other 's value as y for some instance. 让分别表示current的值作为xother的值作为y一些实例。

The value of hashCode is 31*(31+x)+y . hashCode值为31*(31+x)+y

Now, for another instance, if other is x and current is y (which means that second instance should be equal to the first instance), hashCode is now 31*(31+y)+x which is not equal to 31*(31+x)+y for most values of x and y . 现在,对于另一个实例,如果otherx并且currenty (这意味着第二个实例应该等于第一个实例),则hashCode现在为31*(31+y)+x ,不等于31*(31+x)+y适用于xy大多数值。

Hence you are breaking the contract of hashCode , since if a.equals(b) == true , a.hashCode() must be equal to b.hashCode() . 因此,您违反了hashCode的约定,因为如果a.equals(b) == true ,则a.hashCode()必须等于b.hashCode()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM