Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / August 2007

Tip: Looking for answers? Try searching our database.

override equals and hashcode

Thread view: 
lowenbrau - 09 Aug 2007 13:44 GMT
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();
 }
}
}
Lew - 09 Aug 2007 13:52 GMT
> Hi,
>  
[quoted text clipped - 14 lines]
>    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().

Signature

Lew

lowenbrau - 09 Aug 2007 14:22 GMT
>> Hi,
>>  I have a class Obj. I created three objects o1,o2,03. Objects are equal
[quoted text clipped - 18 lines]
>
> You didn't override equals().

default access?
I don't have a subclass? or any package?
Can you be help some more?
Thomas Fritsch - 09 Aug 2007 14:33 GMT
>>>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
[quoted text clipped - 3 lines]
>
> 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?

Signature

Thomas

Patricia Shanahan - 09 Aug 2007 14:33 GMT
>>> Hi,
>>>  I have a class Obj. I created three objects o1,o2,03. Objects are equal
[quoted text clipped - 20 lines]
> 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
Thomas Fritsch - 09 Aug 2007 14:08 GMT
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)
>   {
>    
[quoted text clipped - 4 lines]
>    else return false;
>   }

Signature

Thomas

lowenbrau - 09 Aug 2007 14:24 GMT
> lowenbrau schrieb:
>> Something is not right with the equals or hashcode method. Can someone
[quoted text clipped - 13 lines]
>>     return (this.id.equals(o.id));
>>    else return false; }

Thankyou!
Roedy Green - 10 Aug 2007 04:11 GMT
> 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.
Signature

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Roedy Green - 10 Aug 2007 04:21 GMT
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?
Signature

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Roedy Green - 10 Aug 2007 04:28 GMT
On Fri, 10 Aug 2007 03:21:29 GMT, Roedy Green
<see_website@mindprod.com.invalid> 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);
}
Signature

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.