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

使用equals方法比较两个对象,Java,java,arrays,object,if-statement,equals,Java,Arrays,Object,If Statement,Equals,我有一个要与目标对象进行比较的对象数组。我想返回与目标对象完全匹配的对象数 这是我的计数方法: public int countMatchingGhosts(Ghost target) { int count=0; for (int i=0;i<ghosts.length;i++){ if (ghosts[i].equals(target)); count++; } return

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

这是我的计数方法:

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

我运行了一些测试代码,我希望只有1个匹配,但我得到了3个。你看到错误了吗?

有一个
,则在
的末尾添加code>:

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

这使得
count++方法返回的值是多少,code>总是会发生。

您应该重写此函数:

public boolean equals(Object other) { }
注意方法签名中使用的是
对象
类,而不是
重影
。如果未正确使用方法签名,则可以使用
@Override
注释获取编译器错误

@Override
public boolean equals(Object other) { }

话虽如此,代码中可能发生的事情是另一个答案所说的…

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

下面是约书亚·布洛赫(Joshua Bloch)的书《有效的Java》的节选

第9项:重写等于时始终重写哈希代码

正如Pablo所说,如果在
equals
方法签名中使用
对象
类以外的任何东西,那么实际上并没有重写
equals
方法,程序将无法按预期工作

例如,这个小程序将
列表
复制到
集合
(不能包含重复项)并打印新集合。尝试将
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);
    }
    }
公共类项目{
私有字符串名称;
私人双价;
私人生产;
公共项目(字符串名称、双倍价格、字符串生产国){
这个.setName(name);
这个。设定价格(price);
此。设置生产国(生产国);
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
公开双价{
退货价格;
}
公共定价(双倍价格){
这个价格=价格;
}
公共字符串getCountryOfProduction(){
返回生产国;
}
public void setCountryOfProduction(字符串countryOfProduction){
this.countryOfProduction=生产国;
}
公共字符串toString(){
返回“项名称:”+getName()+“\n”+
“商品价格:N”+getPrice()+”\N”+
“生产国:“+getCountryOfProduction()+”\n”;
}
@凌驾
公共布尔等于(对象obj){
如果(!(项目的obj实例)){
返回false;
}
如果(obj==此){
返回true;
}
项目其他=(项目)obj;
如果(this.getName().equals)(other.getName())
&&this.getPrice()==其他.getPrice()
&&this.getCountryOfProduction().equals(other.countryOfProduction)){
返回true;
}否则{
返回false;
}
}
公共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();
返回散列;
}
公共静态void main(字符串[]args){
列表项=新建ArrayList();
增加(新项目(“棒球棒”,45,“美国”);
增加(新项目(“BLUESEAL凡士林”,1500,“南非”);
增加(新项目(“BLUESEAL凡士林”,1500,“南非”);
集合节点=新哈希集(项);
noDups.stream()
.forEach(System.out::println);
}
}

重影包含哪些字段,以及如何初始化重影?我认为数组具有非唯一值。这就是为什么我总是使用大括号。我花了两天的时间才找到这样的东西。再也不会。。。
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.
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);
    }
    }