简体   繁体   English

在Java中为我的对象实现Equals和hashCode

[英]Implementing Equals and hashCode for my objects in Java

So I know this is widely talked about and discussed and I'm just trying to get my equality working for Shapes. 因此,我知道对此进行了广泛的讨论和讨论,而我只是想让我的平等工作适用于Shapes。 I have created a class Shape that says what type of Shape, (ie rect,triangle,circle) and I'm trying to return true if they are of the same shape. 我创建了一个Shape类,它说明了什么类型的Shape(即矩形,三角形,圆形),并且如果它们具有相同的形状,我将尝试返回true。

In main for testing... 主要用于测试...

Rectangle myRect = new Rectangle(3,5);
Rectangle myRect2 = new Rectangle(3,5);
  if (myRect==myRect2){              
            System.out.println("Both the objects are equal");   
        }          
        else {   
            System.out.println("Both the objects are not equal");  
        } 

and my actual Shape class with overriding equals and hashcode. 和我实际的Shape类,带有覆盖的equals和hashcode。

abstract class Shape
{ 
abstract double area(); 

  public Shape getShape(){
    return shape;
  }

@Override
    public boolean equals(Object other) {
    if (other == this) return true;
    if (other == null) return false;
    if (getClass() != other.getClass()) return false;
    Shape shape = (Shape)other;
   return(other==this);
  }

    @Override
    public int hashCode() {
        return shape.hashCode();
    }

Basically I keep getting false as my output, any insight would be helpful, thanks! 基本上,我的输出总是虚假,任何见解都会有所帮助,谢谢!

myRect==myRect2 returns true only if they are the same objects. myRect==myRect2仅当它们是相同的对象myRect==myRect2返回true You should use myRect.equals(myRect2); 您应该使用myRect.equals(myRect2);

In java, when it comes to objects, using == means checking the address value of object. 在Java中,当涉及对象时,使用==表示检查对象的地址值。 Let me explain this with an example: 让我用一个例子解释一下:

Rectangle objA = new Rectangle(3,5);
Rectangle objB = objA;

Here objA is created on memory location A and objB points to memory location A , or where objA was created. 此处, objA在内存位置A上创建,而objB指向内存位置AobjA创建位置。 This means that both memory locations are the same, meaning that objA == objB will return true. 这意味着两个内存位置相同,这意味着objA == objB将返回true。

But in another case: 但是在另一种情况下:

Rectangle objC = new Rectangle(3,5);
Rectangle objD = new Rectangle(3,5);

You might say, oh they both have the same width and height the same, they must be same objects. 您可能会说,哦,它们的宽度和高度都相同,所以它们必须是相同的对象。 But see, that's not the case, because objC was created on memory location C and objD was created on memory location D , because they were each created with separate new (constructor) call. 但是请注意,事实并非如此,因为objC是在内存位置C上创建的,而objD是在内存位置D上创建的,因为它们每个都是通过单独的new (构造函数)调用创建的。 Memory locations in this case is different, meaning that objC == objD will return false. 在这种情况下,内存位置是不同的,这意味着objC == objD将返回false。

Memory locations aren't named like that, I just used this to easier describe my examples. 内存位置并不是这样命名的,我只是用它来更容易地描述我的示例。


You were thinking right when you wanted to use .equals method, that's what java is using to compare two objects deeper than just their address. 当您想使用.equals方法时,您正在考虑正确,这就是java用来比较两个对象的深度,而不仅仅是它们的地址。 But in custom classes, it's up to user to define how this method works, when two objects are equal and when not. 但是在自定义类中,由用户定义何时两个对象相等以及何时不相等时该方法的工作方式。

But your .equals implementation is a bit faulty. 但是您的.equals实现有点错误。

This line checks if object other is pointing to memory location of this . 这行检查对象other是否指向this存储位置。

if (other == this) return true;

But later, you have these 2 lines: 但是稍后,您有以下两行:

Shape shape = (Shape)other;
return(other==this);

You don't do anything with the shape object, so why even create it, it's just making more work for garbage collector. 您无需对shape对象执行任何操作,因此,为什么还要创建它,也只是为垃圾收集器增加了工作量。 And return other==this is a bit redundant, because if earlier line returns true, only possibility here is to return false, so this check is just more complex version of return false . 并且return other==this有点多余,因为如果前面的行返回true,则这里唯一的可能是返回false,因此此检查只是return false更复杂的版本。


When you're using abstract classes that are later extended by other derived classes, you should implement .equals method in each of those classes. 当您使用稍后由其他派生类扩展的抽象类时,应在每个这些类中实现.equals方法。 Example from your case, you'll probably want to compare two rectangles differently than two circles, right? 以您的案例为例,您可能想要比较两个矩形而不是两个圆形,对吗?

Rather than using one general .equals method, which, frankly, is not any better than using just the == operator, you should implement it for each of derived classes. 坦率地说,与其使用一个通用的.equals方法,而不是仅使用==运算符,不如将其改进,您应该为每个派生类实现它。

I don't know how exactly your Rectangle class looks like, but I'll give it a try: 我不知道您的Rectangle类是什么样子,但我将尝试一下:

public boolean equals(Object other) {
    if (other == this) return true;
    if (other == null) return false;
    if (getClass() != other.getClass()) return false;
    Rectangle rect = (Rectangle) other;
    // compare measures of this and other Rectangle
    return width == rect.width && height == rect.height;
}

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

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