This week's book giveaway is in the Clojure forum.
We're giving away four copies of Clojure in Action and have Amit Rathore and Francis Avila on-line!
See this thread for details.
Win a copy of Clojure in Action this week in the Clojure forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

override the equals and hashcode

 
Gil Shoam
Greenhorn
Posts: 13
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I'm writing a program that represents a graph.
I have 3 classes.
1. a Node class (which takes an object)
2. a Edge class (which build an edge from a source Node to destination Node)
3. A graph class. Here it is:


I'm trying to override the equals and hashcode methods to check if two graphs are similar.
meantime I wrote it just to check the nodes but with no luck:

when I tried

I got:
false
true

in other words I wasn't able to implement the method for the actual Node which contains a char, but only for it's wrapping. for the same reason I am able to add two similar char to the _nodes hashset (which should in theory not be possible). I did so and the did toString and got
Nodes: [A,B,D,A,C]
So it sees is as two different object although I want it to see the two A's as the same (and then it won't add another A right?)
I understand what the problem is, I just don't know how to solve it.

BTW, I wrote equal methods in the Node and Edge classes, both work fine. (in both cases i based the methods on the toString result)
Here:

prints:
A
A
true

and in Edge:

returns:
(C,D)
(C,D)
true


Please Help, and sorry for the long post

Thanks

Gil
 
Ralph Cook
Ranch Hand
Posts: 479
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is where I get lost:

Gil Shoam wrote:

when I tried

I got:
false
true

in other words I wasn't able to implement the method for the actual Node which contains a char, but only for it's wrapping. for the same reason I am able to add two similar char to the _nodes hashset (which should in theory not be possible). I did so and the did toString and got
Nodes: [A,B,D,A,C]
So it sees is as two different object although I want it to see the two A's as the same (and then it won't add another A right?)
I understand what the problem is, I just don't know how to solve it.

I don't know which one 'the method' is. This is the first mention made in your post of a char, which doesn't seem to fit into your class anywhere. Characters, perhaps, but not chars. And I have to assume that this 'nodeA' was added to one (both?) of your instances at some point, you don't say that it is. Anyway, I have now read through this several times and I'm not sure I understand the question. I think it might be clear if you made a series of steps -- instantiate A, add B to its list, add C to its list, instantiate D, etc., and then call equals and show that it exhibits the behavior you don't want.
Gil Shoam wrote:

BTW, I wrote equal methods in the Node and Edge classes, both work fine.


Did you also write hashCode methods for them? Two 'equal' objects are supposed to return the same hashCode; if they don't, things like HashSets could behave unpredictably...

 
Gil Shoam
Greenhorn
Posts: 13
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'll clarify: (the Object identifies and translates 'A' into new Character('A'), so that is not the problem)

this is the Node class:


it prints :
A
A
true

meaning it compares two different nodes and 'equals' checks if they have the same name.

this is the Edge Class:

prints
(C,D)
(C,D)
true

so here the equals also works.

in the graph class i did this:


it prints:
Nodes: [A,D,B,A,C]
Edges: [(A,B),(B,C)(A,C)]
nodes1: [A,C,B,D]
Edges 1:[(A,B),(B,C)(A,C)]
false
true

so there are two problems here.
1) How can I add another 'A' to Nodes? a hashset isn't supposed to allow it. i.e it has two similar elements. I know it sees them as different because it is looking at the 'Node' wrapping.
2) If I erase the extra 'A' from Nodes, and to the equals method again (which currently only checks the _nodes)
it still returns false even though they have the same elements in the set.
the last line gives 'true' because the set has wrapped the Characters with the nodes, so I guess the equals method is comparing that. (So these 2 problems are actually the same I think..?)
That is where I am stuck..
Hope this helps...
 
Ralph Cook
Ranch Hand
Posts: 479
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
From the javadoc for Object.hashCode() (SE 5.0):

"If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. "

You have not shown that you've overridden hashCode, but you have overridden equals to produce true on two different objects. By default, the Object implementation of hashCode would return different values for your two different objects. I don't know that that's your only problem, but it looks likely, and is certainly not what's recommended for equals and hashCode.

rc
 
I agree. Here's the link: http://aspose.com/file-tools
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic