Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > override equals and hashcode

Reply
Thread Tools

override equals and hashcode

 
 
lowenbrau
Guest
Posts: n/a
 
      08-09-2007
Hi,

I have a class Obj. I created three objects o1,o2,03. Objects are equal if their id is equal. For example, o1 and o3 are equal. I tried adding these three objects to a HashSet, and when I print the size of the hashset I get "3" and not "2". Something is not right with the equals or hashcode method. Can someone shed some light?

code snippet:

import java.util.*;

public class Test
{
public static void main (String[] args)
{
Set hs = new HashSet();
Obj o1 = new Obj ("w", 10);
Obj o2 = new Obj ("r", 20);
Obj o3 = new Obj ("w", 30);

hs.add(o1);
hs.add(o2);
hs.add(o3);

System.out.println(hs.size());
}

public static class Obj
{
String id;
int length;

Obj (String id, int length)
{
this.id = id;
this.length = length;
}

boolean equals (Obj o)
{

if (o == null)
return false;
else if (o instanceof Obj)
return (this.id.equals(o.id));
else return false;
}

public int hashCode()
{
return id.hashCode();
}
}
}
 
Reply With Quote
 
 
 
 
Lew
Guest
Posts: n/a
 
      08-09-2007
lowenbrau wrote:
> Hi,
>
> I have a class Obj. I created three objects o1,o2,03. Objects are equal
> if their id is equal. For example, o1 and o3 are equal. I tried adding
> these three objects to a HashSet, and when I print the size of the
> hashset I get "3" and not "2". Something is not right with the equals or
> hashcode method. Can someone shed some light?
>
> code snippet:
> boolean equals (Obj o)
> {
>
> if (o == null)
> return false;
> else if (o instanceof Obj)
> return (this.id.equals(o.id));
> else return false;
> }


From the JLS
<http://java.sun.com/docs/books/jls/third_edition/html/names.html#6.6.5>
> If a public class has a method or constructor with default access, then this method or constructor is not accessible to or inherited by a subclass declared outside this package.


You didn't override equals().

--
Lew
 
Reply With Quote
 
 
 
 
Thomas Fritsch
Guest
Posts: n/a
 
      08-09-2007
lowenbrau schrieb:
> Something is not right with the equals or hashcode method. Can someone shed some light?

[...]
> boolean equals (Obj o)

In order to override
equals(Object o)
you have to declare it as
equals(Object o)
and not
equals(Obj o)
> {
>
> if (o == null)
> return false;
> else if (o instanceof Obj)
> return (this.id.equals(o.id));
> else return false;
> }


--
Thomas
 
Reply With Quote
 
lowenbrau
Guest
Posts: n/a
 
      08-09-2007

"Lew" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed). ..
> lowenbrau wrote:
>> Hi,
>> I have a class Obj. I created three objects o1,o2,03. Objects are equal
>> if their id is equal. For example, o1 and o3 are equal. I tried adding
>> these three objects to a HashSet, and when I print the size of the
>> hashset I get "3" and not "2". Something is not right with the equals or
>> hashcode method. Can someone shed some light?
>> code snippet:
>> boolean equals (Obj o)
>> {
>> if (o == null)
>> return false;
>> else if (o instanceof Obj)
>> return (this.id.equals(o.id));
>> else return false; }

>
> From the JLS
> <http://java.sun.com/docs/books/jls/third_edition/html/names.html#6.6.5>
>> If a public class has a method or constructor with default access, then
>> this method or constructor is not accessible to or inherited by a
>> subclass declared outside this package.

>
> You didn't override equals().
>
> --
> Lew


default access?
I don't have a subclass? or any package?
Can you be help some more?



 
Reply With Quote
 
lowenbrau
Guest
Posts: n/a
 
      08-09-2007
> lowenbrau schrieb:
>> Something is not right with the equals or hashcode method. Can someone
>> shed some light?

> [...]
>> boolean equals (Obj o)

> In order to override
> equals(Object o)
> you have to declare it as
> equals(Object o)
> and not
> equals(Obj o)
>> {
>> if (o == null)
>> return false;
>> else if (o instanceof Obj)
>> return (this.id.equals(o.id));
>> else return false; }

>
> --
> Thomas


Thankyou!


 
Reply With Quote
 
Thomas Fritsch
Guest
Posts: n/a
 
      08-09-2007
lowenbrau wrote:
>>>If a public class has a method or constructor with default access, then
>>>this method or constructor is not accessible to or inherited by a
>>>subclass declared outside this package.

>>
>>You didn't override equals().

>
> default access?

He means: If the overridden method is public (in your case:
equals(Object) of class java.lang.Object), then the overriding method
(in your case: equals(Object) of your class Obj) must be public too.
Doing not so will cause the compiler to complain.
> I don't have a subclass? or any package?

You *have* a subclass: Your class Obj is a subclass of java.lang.Object.
You also *have* a package (the name-less default package), which is
different from the package "java.lang".
> Can you be help some more?



--
Thomas
 
Reply With Quote
 
Patricia Shanahan
Guest
Posts: n/a
 
      08-09-2007
lowenbrau wrote:
> "Lew" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed). ..
>> lowenbrau wrote:
>>> Hi,
>>> I have a class Obj. I created three objects o1,o2,03. Objects are equal
>>> if their id is equal. For example, o1 and o3 are equal. I tried adding
>>> these three objects to a HashSet, and when I print the size of the
>>> hashset I get "3" and not "2". Something is not right with the equals or
>>> hashcode method. Can someone shed some light?
>>> code snippet:
>>> boolean equals (Obj o)
>>> {
>>> if (o == null)
>>> return false;
>>> else if (o instanceof Obj)
>>> return (this.id.equals(o.id));
>>> else return false; }

>> From the JLS
>> <http://java.sun.com/docs/books/jls/third_edition/html/names.html#6.6.5>
>>> If a public class has a method or constructor with default access, then
>>> this method or constructor is not accessible to or inherited by a
>>> subclass declared outside this package.

>> You didn't override equals().
>>
>> --
>> Lew

>
> default access?
> I don't have a subclass? or any package?
> Can you be help some more?
>
>
>


The equals method in Object is declared "public boolean equals(Object obj)"

To override it, you must declare an equals with the same signature. The
only thing you can safely change is the identifier for the parameter:

public boolean equals(Object o)

is fine. Changing anything else will prevent your method from overriding
the Object equals.

Note that when testing an equals implementation it is important to
include tests where the parameter has type Object, even if it references
an instance of your class:

Test someTest = new Test...
Object o1 = someTest;

and use o1 as the equals parameter. That is how it will be used, in
effect, in java.util collections.

[If it were "public boolean equals(SomeClass obj)" you could replace
"SomeClass" with a superclass or super-interface. Object has no
superclasses, so that is not an option for equals.]

Patricia
 
Reply With Quote
 
Roedy Green
Guest
Posts: n/a
 
      08-10-2007
> boolean equals (Obj o)
when you override you must exactly match the signature of the beast in
base class. equals should be public.
I have not experimented with the @override annotation to make sure it
generates an error message if my signature does not exactly match
something in the base class.
--
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
 
Reply With Quote
 
Roedy Green
Guest
Posts: n/a
 
      08-10-2007
The signature must exactly match:
public boolean equals( Object o )
not
boolean equals( Obj o )
Unfortunately you won't get an error message. Javac does not know you
are trying to override equals. It thinks you are making up an
overloaded variant.

>if (o == null)
> return false;
> else if (o instanceof Obj)
> return (this.id.equals(o.id));
> else return false;

If you ever fed that to IntelliJ likely it would ask if you wanted it
converted to:
return o != null && o instanceof Obj && this.id.equals(o.id);
What does instanceof do with nulls?
--
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
 
Reply With Quote
 
Roedy Green
Guest
Posts: n/a
 
      08-10-2007
On Fri, 10 Aug 2007 03:21:29 GMT, Roedy Green
<(E-Mail Removed)> wrote, quoted or indirectly quoted
someone who said :

> return o != null && o instanceof Obj && this.id.equals(o.id);
>What does instanceof do with nulls?


null instanceof SomeClass is always false.

Therefore you can collapse that expression to:
return o instanceof Obj && this.id.equals(o.id);
The way you wrote your code, o HAD to be an Obj so the instanceof was
nugatory.

Had you written the code correctly, there could be some doubt.

e.g.

public boolean equals (Object o)
{
return o instanceof Obj && this.id.equals(((Obj)o).id);
}
--
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Be Honest: Do you implement hashCode(), equals(), and toString() for every class you write? Danno Java 29 09-15-2006 11:00 PM
equals() and hashcode() not working... e.chaitanya@gmail.com Java 6 04-11-2006 04:55 PM
equals and hashCode Tom Dyess Java 28 06-23-2005 05:29 PM
Infinite loops in hashCode() and equals() Mike Schilling Java 11 06-12-2004 04:46 AM
equals and hashCode Gregory A. Swarthout Java 2 12-20-2003 12:34 AM



Advertisments