Hello,
I have a questions about how the contains() method works for a class in Collection framework with a user defined object. Do I have to do something special?
I tried the following example. But the output is not what I expected.
--------------- CODE --------------------
import java.util.*;
class Lane
{ int SNode, DNode;
public Lane(int SN, int DN)
{ SNode=SN; DNode=DN; }
public boolean equals(Lane o)
{ if(o.SNode==SNode && o.DNode==DNode) return true;
else return false;
}
};
class Bundle
{ HashSet<Lane> Lanes;
public Bundle(){ Lanes=new HashSet<Lane>(); }
public boolean add(Lane l){ return Lanes.add(l); }
public boolean contains(Lane l){ return Lanes.contains(l); }
public void printAll()
{ System.out.print("[ ");
for(Lane l : Lanes){ System.out.print("("+l.SNode+","+l.DNode+") "); }
System.out.println("]");
}
};
public class Test
{
public static void main(String[] args)
{ Lane L1=new Lane(1,2), L2=new Lane(1,3);
Bundle B=new Bundle();
B.add(L1);
B.add(L2);
B.printAll();
if(B.contains(L2)) System.out.println("Bundle has L2");
if(B.contains(new Lane(1,3))) System.out.println("Bundle has (1,3)");
}
}
-------------- OUTPUT ------------
[ (1,3) (1,2) ]
Bundle has L2
---------------------------------
I was expecting to see "Bundle has (1,3)" in the output. My impression was that contains method internally calls equals method of the object concerned, so I even defined my own equals(). Still it did not work. What am I missing?
Also, one secondary question. I am sure this question has been discussed in many texts and newsgroup messages, but with google I couldn't find. What will be the exact set of keywords for my case to search? I tried [java "contains method" "user defined object"], [java Collection "contains method"] etc.
Thanks.

Signature
Please reply to the newsgroup.
To mail me directly, replace 'K' with 'e'.
Thomas Hawtin - 25 Oct 2005 18:58 GMT
> I have a questions about how the contains() method works for a class in
> Collection framework with a user defined object. Do I have to do
> something special?
> public boolean equals(Lane o)
> { if(o.SNode==SNode && o.DNode==DNode) return true;
> else return false;
> }
This does not override Object.equals(Object). You need something like:
@Override // 1.5+ only
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
// If class was final, could use if (!(obj instanceof Lane))
if (obj == null || !(this.getClass() != obj.getClass)) {
return false;
}
Lane other = (Lane)obj;
return
this.sNode == other.sNode &&
this.dNode == other.dNode;
}
Whenever you override equals, you should also override hashCode (and
probably toString). See the java.lang.Object JavaDocs for details.
@Override
public int hashCode() {
return sNode*37 + dNode;
}
It's probably best to make the class and member variables final.
Tom Hawtin

Signature
Unemployed English Java programmer
http://jroller.com/page/tackline/
Samik R - 26 Oct 2005 01:32 GMT
> This does not override Object.equals(Object). You need something like:
>
[quoted text clipped - 24 lines]
>
> Tom Hawtin
Thanks Tom. Really appreciate your time.

Signature
Please reply to the newsgroup.
To mail me directly, replace 'K' with 'e'.
Roedy Green - 26 Oct 2005 02:17 GMT
On Tue, 25 Oct 2005 18:58:50 +0100, Thomas Hawtin
<usenet@tackline.plus.com> wrote, quoted or indirectly quoted someone
who said :
> public int hashCode() {
> return sNode*37 + dNode;
> }
for more notes on composing hashCode methods, see
http://mindprod.com/jgloss/hashcode.html

Signature
Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.