override equals and hashcode

Discussion in 'Java' started by lowenbrau, Aug 9, 2007.

  1. lowenbrau

    lowenbrau Guest

    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();
    }
    }
    }
    lowenbrau, Aug 9, 2007
    #1
    1. Advertising

  2. lowenbrau

    Lew Guest

    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
    Lew, Aug 9, 2007
    #2
    1. Advertising

  3. 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
    Thomas Fritsch, Aug 9, 2007
    #3
  4. lowenbrau

    lowenbrau Guest

    "Lew" <> wrote in message
    news:...
    > 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?
    lowenbrau, Aug 9, 2007
    #4
  5. lowenbrau

    lowenbrau Guest

    > 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!
    lowenbrau, Aug 9, 2007
    #5
  6. 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
    Thomas Fritsch, Aug 9, 2007
    #6
  7. lowenbrau wrote:
    > "Lew" <> wrote in message
    > news:...
    >> 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
    Patricia Shanahan, Aug 9, 2007
    #7
  8. lowenbrau

    Roedy Green Guest

    > 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
    Roedy Green, Aug 10, 2007
    #8
  9. lowenbrau

    Roedy Green Guest

    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
    Roedy Green, Aug 10, 2007
    #9
  10. lowenbrau

    Roedy Green Guest

    On Fri, 10 Aug 2007 03:21:29 GMT, Roedy Green
    <> 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
    Roedy Green, Aug 10, 2007
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Gregory A. Swarthout

    equals and hashCode

    Gregory A. Swarthout, Dec 19, 2003, in forum: Java
    Replies:
    2
    Views:
    350
    Silvio Bierman
    Dec 20, 2003
  2. Mike Schilling
    Replies:
    11
    Views:
    1,398
    Mike Schilling
    Jun 12, 2004
  3. Tom Dyess

    equals and hashCode

    Tom Dyess, Jun 19, 2005, in forum: Java
    Replies:
    28
    Views:
    906
    Virgil Green
    Jun 23, 2005
  4. Replies:
    6
    Views:
    467
    Alex Hunsley
    Apr 11, 2006
  5. Danno
    Replies:
    29
    Views:
    885
    Jeffrey Schwab
    Sep 16, 2006
Loading...

Share This Page