使用 equals 方法比较两个对象,Java

发布于 2024-09-27 23:20:07 字数 771 浏览 1 评论 0原文

我有一个对象数组,我想将它们与目标对象进行比较。我想返回与目标对象完全匹配的对象数量。

这是我的 count 方法:

public int countMatchingGhosts(Ghost target) {
        int count=0;
        for (int i=0;i<ghosts.length;i++){
            if (ghosts[i].equals(target));
            count++;
        }
        return count;

这是我的 equals 方法:

public boolean equals(Ghost other){
           if(this == other) return true;
           if( !(other instanceof Ghost) ) return false;
           Ghost p = (Ghost)other;

        if (this.x == p.x && this.y == p.y && this.direction==p.direction && this.color.equals(p.color))
            return true;
        else
            return false;

我运行一些测试代码,我期望仅匹配 1 个,但我得到 3 个。您看到任何错误吗?

I have an array of objects that I want to compare to a target object. I want to return the number of objects that exactly match the target object.

Here is my count method:

public int countMatchingGhosts(Ghost target) {
        int count=0;
        for (int i=0;i<ghosts.length;i++){
            if (ghosts[i].equals(target));
            count++;
        }
        return count;

And here is my equals method:

public boolean equals(Ghost other){
           if(this == other) return true;
           if( !(other instanceof Ghost) ) return false;
           Ghost p = (Ghost)other;

        if (this.x == p.x && this.y == p.y && this.direction==p.direction && this.color.equals(p.color))
            return true;
        else
            return false;

I run some test code, and I expect 1 matching only, but I get 3 instead. Do you see any errors?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

信仰 2024-10-04 23:20:07

if 末尾有一个 ;

if (ghosts[i].equals(target));
                             ^

这使得 count++; 总是发生,无论您的 < code>equals 方法返回。

There is a ; at the end of your if:

if (ghosts[i].equals(target));
                             ^

This makes count++; happen always irrespective of what your equals method returns.

蓝咒 2024-10-04 23:20:07

您应该重写此函数:

public boolean equals(Object other) { }

请注意方法签名中使用的是 Object 类,而不是 Ghost。如果您没有正确使用方法签名,则可以使用 @Override 注释来获取编译器错误。

@Override
public boolean equals(Object other) { }

话虽如此,您的代码中可能发生的情况就是另一个答案所说的......

You should override this function:

public boolean equals(Object other) { }

Do note the Object class being used in method's signature instead of Ghost. Your can use @Override annotation to get a compiler error if you are not using method signature correctly.

@Override
public boolean equals(Object other) { }

Having said that, what's probably happening in your code is what the other answer is stating...

你的往事 2024-10-04 23:20:07

只是想我补充一点,在代码中实现 equals 方法时,您还必须实现(覆盖)hashCode 方法。这是一份总合同,您必须遵守才能获得最佳表现。

以下是 Joshua Bloch 的书 “Effective Java” 的摘录

第 9 项:重写 equals 时始终重写 hashCode

A common source of bugs is the failure to override the hashCode method. You
must override hashCode in every class that overrides equals. Failure to do so
will result in a violation of the general contract for Object.hashCode, which will
prevent your class from functioning properly in conjunction with all hash-based
collections, including HashMap,HashSet, and Hashtable.
Here is the contract, copied from the Object specification [JavaSE6]:
• Whenever it is invoked on the same object more than once during an execution
  of an application, the hashCode method must consistently return the
  same integer, provided no information used in equals comparisons on the
  object is modified. This integer need not remain consistent from one execution
  of an application to another execution of the same application.
• If two objects are equal according to the equals(Object) method, then calling
  the hashCode method on each of the two objects must produce the same
  integer result.

就像 Pablo 所说,如果您在 equals 方法签名中使用除 Object 类以外的任何内容,那么您实际上并不是覆盖 equals 方法,您的程序将无法按预期运行。

以这个小程序为例,它将 List 复制到 Set(不能包含重复项)并打印新的 Collection。尝试将 equals(Object obj)equals(Item obj) 交换,看看运行程序时会发生什么。另外,注释掉 hashCode() 方法并运行程序,观察使用它和不使用它之间的区别。

public class Item {
      private String name;
      private double price;
      private String countryOfProduction;

public Item(String name, double price, String countryOfProduction) {
    this.setName(name);
    this.setPrice(price);
    this.setCountryOfProduction(countryOfProduction);
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public double getPrice() {
    return price;
}

public void setPrice(double price) {
    this.price = price;
}

public String getCountryOfProduction() {
    return countryOfProduction;
}

public void setCountryOfProduction(String countryOfProduction) {
    this.countryOfProduction = countryOfProduction;
}

public String toString() {
    return "Item Name: " + getName() + "\n" +
            "Item Price: N" + getPrice() + "\n" +
            "Country of Production: " + getCountryOfProduction() + "\n";
}

@Override
public boolean equals(Object obj) {
    if(!(obj instanceof Item)) {
        return false;
    }
    if(obj == this) {
        return true;
    }

    Item other = (Item)obj;
    if(this.getName().equals(other.getName())
              && this.getPrice() == other.getPrice() 
              && this.getCountryOfProduction().equals(other.countryOfProduction)) {
        return true;
    } else {
        return false;
    }

}

public int hashCode() {
    int hash = 3;

    hash = 7 * hash + this.getName().hashCode();
    hash = 7 * hash + this.getCountryOfProduction().hashCode();
    hash = 7 * hash + Double.valueOf(this.getPrice()).hashCode();
    return hash;

}

public static void main (String[]args) {

    List<Item> items = new ArrayList<>();


    items.add(new Item("Baseball bat", 45, "United States"));
    items.add(new Item("BLUESEAL Vaseline", 1500, "South Africa"));
    items.add(new Item("BLUESEAL Vaseline", 1500, "South Africa"));


    Collection<Item> noDups = new HashSet<>(items);


    noDups.stream()                      
            .forEach(System.out::println);
    }
    }

Just thought I add that while implementing the equals method in your code, you must also implement (override) the hashCode method. This is a general contract that you must follow for the best performances.

Below is an excerpt from Joshua Bloch's book "Effective Java"

Item 9: Always override hashCode when you override equals

A common source of bugs is the failure to override the hashCode method. You
must override hashCode in every class that overrides equals. Failure to do so
will result in a violation of the general contract for Object.hashCode, which will
prevent your class from functioning properly in conjunction with all hash-based
collections, including HashMap,HashSet, and Hashtable.
Here is the contract, copied from the Object specification [JavaSE6]:
• Whenever it is invoked on the same object more than once during an execution
  of an application, the hashCode method must consistently return the
  same integer, provided no information used in equals comparisons on the
  object is modified. This integer need not remain consistent from one execution
  of an application to another execution of the same application.
• If two objects are equal according to the equals(Object) method, then calling
  the hashCode method on each of the two objects must produce the same
  integer result.

And just like Pablo said, if you use anything other than the Object class in your equals method signature, you aren't actually overriding the equals method, and your program won't work as expected.

Take for example this small program that copies a List to a Set(which cannot contain duplicates) and prints the new Collection. Try swapping equals(Object obj) with equals(Item obj) and see what happens when you run the program. Also, comment out the hashCode() method and run the program and observe the difference between using it and not.

public class Item {
      private String name;
      private double price;
      private String countryOfProduction;

public Item(String name, double price, String countryOfProduction) {
    this.setName(name);
    this.setPrice(price);
    this.setCountryOfProduction(countryOfProduction);
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public double getPrice() {
    return price;
}

public void setPrice(double price) {
    this.price = price;
}

public String getCountryOfProduction() {
    return countryOfProduction;
}

public void setCountryOfProduction(String countryOfProduction) {
    this.countryOfProduction = countryOfProduction;
}

public String toString() {
    return "Item Name: " + getName() + "\n" +
            "Item Price: N" + getPrice() + "\n" +
            "Country of Production: " + getCountryOfProduction() + "\n";
}

@Override
public boolean equals(Object obj) {
    if(!(obj instanceof Item)) {
        return false;
    }
    if(obj == this) {
        return true;
    }

    Item other = (Item)obj;
    if(this.getName().equals(other.getName())
              && this.getPrice() == other.getPrice() 
              && this.getCountryOfProduction().equals(other.countryOfProduction)) {
        return true;
    } else {
        return false;
    }

}

public int hashCode() {
    int hash = 3;

    hash = 7 * hash + this.getName().hashCode();
    hash = 7 * hash + this.getCountryOfProduction().hashCode();
    hash = 7 * hash + Double.valueOf(this.getPrice()).hashCode();
    return hash;

}

public static void main (String[]args) {

    List<Item> items = new ArrayList<>();


    items.add(new Item("Baseball bat", 45, "United States"));
    items.add(new Item("BLUESEAL Vaseline", 1500, "South Africa"));
    items.add(new Item("BLUESEAL Vaseline", 1500, "South Africa"));


    Collection<Item> noDups = new HashSet<>(items);


    noDups.stream()                      
            .forEach(System.out::println);
    }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文