Java 将类与不带hashCode和equals的类实例进行比较

Java 将类与不带hashCode和equals的类实例进行比较,java,equals,hashcode,Java,Equals,Hashcode,是否可以比较包含其他类实例的类,不包含hashCode和equals public class Car { private long carId; private String manufacturer; public Car(long carId, String manufacturer) { super(); this.carId = carId; this.manufacturer = manufacturer; } /** * @

是否可以比较包含其他类实例的类,不包含hashCode和equals

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;
  }
}
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;
    } }
我们有3个类:Car.java、SUV.java和TestFinal.java

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

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

TestFinal是主类,我在其中比较两个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)

返回false,因为Car不包含对equals和hashCode的重写。有没有什么方法可以更新我的SUV覆盖逻辑,而无需对Car进行更改(比如添加equals和hashCode),从而

suv1.equals(suv2)

返回true

任何投入或建议都是有价值的


谢谢

对于
equals
逻辑,您可以使用一种非常难看的解决方法:手动比较组成两个
SUV
对象的
汽车
对象的相关属性

基本上:

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

我仍然强烈建议不要这样做——更不用说你会因为
hashCode
而遇到的麻烦了

另一种可能适合的方法是,在实现
SUV
等于
hashCode
时,将
Car
作为相关的比较术语删除,并确定两个
SUV
之间的相等性不受其
Car
的影响

最后:SUV不应该是一辆
汽车
,而不是拥有一辆
汽车

有没有什么方法可以更新我的SUV覆盖逻辑而不需要 Car中的更改(如添加equals和hashCode)

不太可能,因为在
SUV.equals()
方法中

else if (!car.equals(other.car))
{
    return false;
}
由于
car.equals()
没有被覆盖,因此它使用
Object.equals()
来简单地比较对象的实例相等性

好吧,你可以用比较
car
中的每个字段来替换该代码,但是你真的想这样做吗?很难看。最好只覆盖
Car.equals()

我已经更新了“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类实现可比较的接口,然后在方法compareTo(to)的实现中编写您自己的逻辑来比较SUV。您还可以创建一个类来实现Comapartor接口,该接口将SUV与您自己的逻辑进行比较。在Javadoc中阅读:和。但这是一个难看的解决方案,实现hashcode和使用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;
        }
    }
    
  }

}

希望,这有帮助….

我想你可以创建覆盖这些方法的包装类,某种程度上是在装饰设计模式中,作为解决这个问题的一种方法,但我认为这会帮助我们理解这个请求背后的动机——为什么不覆盖hashCode和equals,处理这类事情的通常方法是什么?
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;
  }

}