繁体   English   中英

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

[英]Comparing two objects using an equals method, Java

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

这是我的计数方法:

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

这是我的平等方法:

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个。 你看到有什么错误吗?

有一个; 在你的if结束if

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

这使得count++; 无论你的equals方法返回什么, 都会发生。

您应该覆盖此功能:

public boolean equals(Object other) { }

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

@Override
public boolean equals(Object other) { }

话虽如此,你的代码中可能发生的是另一个答案是......

刚想我在代码中实现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(Item obj)交换equals(Object 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);
    }
    }

暂无
暂无

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

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