Java overriding equals, array
Here's a code I'm working on, overriding equals. I've not tried compiling, but Netbeans is giving me a warning saying .equals on incompatible types.
pub开发者_运维技巧lic class Customers {
private String name;
public Customers(name) {
this.name = name;
}
public boolean equals(String name) {
return (this.name.equals(name));
}
}
Main Class
public class TestCustomers {
public static void main(String args[]) {
Customers cus = new Customers[1];
cus[1] = new Customers("John");
if(cus[1].equals("John")
...
}
}
This works fine without using Array. But with array, it shows me a warning.
Why does it gives me a warning saying that .equals on incompatible types? Has this got to do with because of Type Erasures in Array?
The complaint may be because
public boolean equals(String name)
doesn't really override the Object.equals
-method, since Objects.equals
takes an Object
as argument, and not a String
. (This would probably be evident if you took the habit of explicitly writing @Override
in front of the methods you intended to override other methods.)
Saying that a Customer
can equal
anything but a Customer
seems like a really bad idea to me though. I would do something like this:
class Customer {
private String name;
public Customer(String name) {
this.name = String.valueOf(name);
}
public String getName() {
return name;
}
@Override
public boolean equals(Object o) {
return (o instanceof Customer) && ((Customer) o).name.equals(name);
}
@Override
public int hashCode() {
return name.hashCode();
}
}
And the main class:
public class Main {
public static void main(String args[]) {
Customer[] cus = new Customer[1];
cus[0] = new Customer("John");
// Compare against name
if (cus[0].getName().equals("John"))
System.out.println("Name equals.");
// Compare against another customer:
if (cus[0].equals(new Customer("John")))
System.out.println("Customer equals.");
}
}
// Wrong
public boolean equals(String name) {
return (this.name.equals(name));
}
// Correct Way to override equals from Object.
// How about this implementation.
public boolean equals(Object obj) {
if ( obj == null )
return false;
if ( obj == this )
{
return true;
}
if ( getClass() != obj.getClass())
{
return false;
}
Customer cust = (Customer) obj;
if ( this.getName().equals(cust.getName()))
{
return true;
}
else
{
return false;
}
}
However using Apache Commons Equalsbuilder is the best way to go which does deep checking. http://commons.apache.org/lang/api-2.4/org/apache/commons/lang/builder/EqualsBuilder.html
I have a feeling that what the compiler is complaining about is nothing to do with overloading (or in your case trying to overload) equals
.
Customers cus = new Customers[1];
cus[1] = new Customers("John");
if (cus[1].equals("John")) {
The problem here is that cus
has been declared as a Customers
not as a Customers[]
. So the compiler is getting really confused about what cus[1]
means and is (probably) giving it an undefined type. Then it is saying that the undefined type does not support equals
.
If you change:
Customers cus = new Customers[1];
to
Customers[] cus = new Customers[1];
you'll get rid if a bunch of error messages, including (I suspect) the one about equals
. Then you need to go back and address the problems with your definition of equals
... and other errors such as the fact that cus[1]
will throw an ArrayIndexOutOfBoundException
.
Why does it gives me a warning saying that .equals on incompatible types?
I think you've managed to confuse the compiler by attempting to index a variable whose type is not an array; see above.
Has this got to do with because of Type Erasures in Array?
No. The type erasure issue applies solely to generic types; i.e. types that involve type parameters. You don't have any type parameters.
- Change the type of "
cus
" to "Customers [] cus
"Customers [] cus = ...
- Add a String parameter type to the Customers constructor
- Access item 0 (zero), not 1 (one) - First item in Java arrays is index 0.
- Change the "equals" method parameter type to "Object" not String
- Add the "hashCode" method - hashCode should be overridden any time you overide equals (see "Effective Java", Item 9
- The equals method should have the following attributes (see "Effective Java", Item 8)
- o1.equals(null) == false
- reflexive (x.equals(x)==true)
- symmetric; x.equals(y) can return true only if y.equals(x)
- Transitive; if o1.equals(o2) and o2.equals(o3), then o1.equals(o3)
- Consistent; o1.equals(o2) must always return same result (assuming neither object is changed)
"Effective Java" is a great book, well worth reading!
精彩评论