比较 class 和 class 没有 hashCode 和 equals 的实例

Comparing class with class instances without hashCode and equals

是否可以比较包含一些其他 class 实例的 Class,不包含 hashCode 和 equals

我们有 3 个 class:Car.java、SUV.java 和 TestFinal.java

Car.java(没有 hashCode 和 equals 的简单 POJO)

public class Car
{
  private long carId;
  private String manufacturer;

  public Car(long carId, String manufacturer)
  {
    super();
    this.carId = carId;
    this.manufacturer = manufacturer;
  }

  /**
   * @return The carId.
   */
  public long getCarId()
  {
      return carId;
  }

  /**
   * @param carId The carId to set.
   */
  public void setCarId(long carId)
  {
      this.carId = carId;
  }

  /**
   * @return The manufacturer.
   */
   public String getManufacturer()
   {
      return manufacturer;
   }

  /**
   * @param manufacturer The manufacturer to set.
   */
  public void setManufacturer(String manufacturer)
  {
      this.manufacturer = manufacturer;
  }
}

SUV.java(包含 car 的实例并包含 hashCode 和 equals)

public class SUV {
    private Car car;

    /**
     * @return The car.
     */
    public Car getCar()
    {
        return car;
    }

    /**
     * @param car The car to set.
     */
    public void setCar(Car car)
    {
        this.car = car;
    }

    public SUV(Car car)
    {
        super();
        this.car = car;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((car == null) ? 0 : car.hashCode());
        return result;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(Object obj)
    {
        if (this == obj)
        {
            return true;
        }
        if (obj == null)
        {
            return false;
        }
        if (getClass() != obj.getClass())
        {
            return false;
        }
        SUV other = (SUV) obj;
        if (car == null)
        {
            if (other.car != null)
            {
                return false;
            }
        }
        else if (!car.equals(other.car))
        {
            return false;
        }
        return true;
    } }

TestFinal 是主要的 class ,我在这里比较两个 SUV 对象

public class TestFinal
{
    public static void main(String args[])
    {
        Car car1 = new Car(1, "Toyota");
        Car car2 = new Car(1, "Toyota");

        SUV suv1 = new SUV(car1);
        SUV suv2 = new SUV(car2);

        System.out.println(suv1.equals(suv2));
    }
}

这里

suv1.equals(suv2)

returns false ,因为 Car 不包含对 equals 和 hashCode 的覆盖。有没有什么方法可以更新我的 SUV 的重写逻辑而不改变 Car(比如添加 equals 和 hashCode)这样

suv1.equals(suv2)

returns 真

任何意见或建议都是有价值的。

谢谢!!

对于 equals 逻辑,您可以使用一个非常丑陋的解决方法:手动比较组成您正在比较的两个 SUV 对象的 Car 对象的相关属性.

本质上:

if (other.car.getManufacturer().equals(car.getManufacturer()))

我仍然强烈反对这样做 - 更不用说 hashCode 带来的麻烦了!!

另一种可能适合的方法是在实施 SUVequalshashCode 时删除作为相关比较项的 Car,并确定相等性两个 SUVs 之间不受它们的 Cars 的影响。

最后:不应该 SUV Car,而是 Car?

Is there way I can update my Overriding logic of SUV without making changes in Car (like adding equals and hashCode)

不是真的,因为在您的 SUV.equals() 方法中,您有

else if (!car.equals(other.car))
{
    return false;
}

并且由于 car.equals() 未被覆盖,它使用 Object.equals() 简单地比较对象的实例相等性。

好吧,您可以通过单独比较 car 中的每个字段来替换该代码,但您真的要这样做吗?它很丑。最好只覆盖 Car.equals().

我已经更新了 class "SUV",我并不是说这是理想的方式,而是一种解决方法...

public class SUV {
    private Car car;

    /**
     * @return The car.
     */
    public Car getCar() {
        return car;
    }

    /**
     * @param car
     *            The car to set.
     */
    public void setCar(Car car) {
        this.car = car;
    }

    public SUV(Car car) {
        super();
        this.car = car;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((car == null) ? 0 : car.hashCode());
        return result;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        SUV other = (SUV) obj;
        if (car == null) {
            if (other.car != null) {
                return false;
            }
        } else if (!carEquals(car, other.car)) {
            return false;
        }
        return true;
    }

    private boolean carEquals(Car firstObj, Car otherObj){


        if(otherObj == null){
            return false;
        } else{
            if(firstObj.getCarId() == otherObj.getCarId() && firstObj.getManufacturer().equals(otherObj.getManufacturer())){
                return true;
            } else {
                return false;
            }
        }

    }
}

您可以让您的 SUV class 实现 Comparable 接口,然后在方法 compareTo(T o) 的实现中编写您自己的逻辑来比较 SUV,您也可以创建一个 class将实现 Comapartor 接口,将 SUV 与您自己的逻辑进行比较。在 Javadoc 中阅读它:Comparable and Comparator。但这是一个丑陋的解决方法和实现哈希码并且绝对等于更可取

使用比较器接口也如下:

import java.util.Comparator;

public class CarComparator implements Comparator<Car>{

@Override
public int compare(Car o1, Car o2) {
    if(o1 == null || o2 == null){
        return -1;
    } else if(o1!=null && o2 == null){
        return -1;
    } else if(o1==null && o2!=null){
        return -1;
    } else{
        if(o1.getCarId() == o2.getCarId() && o1.getManufacturer().equals(o2.getManufacturer())){
            return 0;
        } else {
            return -1;
        }
    }
    
  }

}

然后是 SUV Class :

package test.corejava.concepts;

public class SUV {
private Car car;

/**
 * @return The car.
 */
public Car getCar() {
    return car;
}

/**
 * @param car
 *            The car to set.
 */
public void setCar(Car car) {
    this.car = car;
}

public SUV(Car car) {
    super();
    this.car = car;
}

/**
 * {@inheritDoc}
 */
@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((car == null) ? 0 : car.hashCode());
    return result;
}

/**
 * {@inheritDoc}
 */
@Override
public boolean equals(Object obj) {
    if (this == obj) {
        return true;
    }
    if (obj == null) {
        return false;
    }
    if (getClass() != obj.getClass()) {
        return false;
    }
    SUV other = (SUV) obj;
    if (car == null) {
        if (other.car != null) {
            return false;
        }
    } else if (new CarComparator().compare(car, other.car)!=0) {
        return false;
    }
    return true;
  }

}

希望,这对您有所帮助....