比较 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
带来的麻烦了!!
另一种可能适合的方法是在实施 SUV
的 equals
和 hashCode
时删除作为相关比较项的 Car
,并确定相等性两个 SUV
s 之间不受它们的 Car
s 的影响。
最后:不应该 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;
}
}
希望,这对您有所帮助....
是否可以比较包含一些其他 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
带来的麻烦了!!
另一种可能适合的方法是在实施 SUV
的 equals
和 hashCode
时删除作为相关比较项的 Car
,并确定相等性两个 SUV
s 之间不受它们的 Car
s 的影响。
最后:不应该 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;
}
}
希望,这对您有所帮助....