HashSet with complicated objects

M

Mike

Hey!

I'm new to Java and want to try to do things properly, so would be
grateful for guidance on the following.

I have a HashSet of fairly complicated objects, and don't want to
instantiate a new one to use the "contains" method to see if the object
exists in the HashSet. Nonetheless, I need to find out if the nascent
object is in the Set (specifically, if I did create a new instance, would
it be the same as one already there).

So, my question is:

1. Is there an idiomatic way to do this, or
2. Has the entire fleet left with me standing on the dock?

Many thanks.

Regards,

Mike
 
W

William Brogden

Hey!

I'm new to Java and want to try to do things properly, so would be
grateful for guidance on the following.

I have a HashSet of fairly complicated objects, and don't want to
instantiate a new one to use the "contains" method to see if the object
exists in the HashSet. Nonetheless, I need to find out if the nascent
object is in the Set (specifically, if I did create a new instance, would
it be the same as one already there).

So, my question is:

1. Is there an idiomatic way to do this, or
2. Has the entire fleet left with me standing on the dock?

Recall that contains() will use only hashCode() and equals() methods
so it all depends on how your objects implement those methods.
If there is a way to make a "lightweight" instance of one of
these objects that will produce the same hashcode and equals
results as a "heavyweight" object, you can use it as a probe
for the HashSet.

Bill
 
T

Tony Morris

Mike said:
Hey!

I'm new to Java and want to try to do things properly, so would be
grateful for guidance on the following.

I have a HashSet of fairly complicated objects, and don't want to
instantiate a new one to use the "contains" method to see if the object
exists in the HashSet. Nonetheless, I need to find out if the nascent
object is in the Set (specifically, if I did create a new instance, would
it be the same as one already there).

So, my question is:

1. Is there an idiomatic way to do this, or
2. Has the entire fleet left with me standing on the dock?

Many thanks.

Regards,

Mike

The fact that you are talking about a HashSet implies that you aren't doing
things the right way.
Specifically, you should be handling types with an interface reference, such
as a java.util.Set.

Here is an example:
Set<?> s = new HashSet<?>();

So now you are talking about a Set - the underlying implementation being
less relevant, since implementation details are always less relevant than
the exposed interface when things are done the "correct way".
The contains() method of Set performs in a very specific way. If you are
storing your own types, it might be worthwhile to override the Object.equals
and Object.hashCode methods so that Set.contains() performs as you desire
(this is also the "correct approach" that you are seeking). Now, I've seen
these methods overridden hundreds of times - but only 0.1% have I seen it
done correctly. The API specification is very precise about the general
contracts of these two methods - ensure that you meet that contract or the
consequences are dire (and often under-estimate).

Here are some links of interest:

The two Object method contracts (which are interrelated - not independant of
each other):
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html#equals(java.lang.Object)
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html#hashCode()

Set.contains()
http://java.sun.com/j2se/1.5.0/docs/api/java/util/Set.html#contains(java.lang.Object)

These third-party (authored by myself) data types will ensure that you have
met the general contracts for your type:
http://www.xdweb.net/~dibblego/junitx/javadoc/junitx/framework/util/EqualsContractTester.html
http://www.xdweb.net/~dibblego/junitx/javadoc/junitx/framework/util/EqualsContractTesterFactory.html
http://www.xdweb.net/~dibblego/junitx/javadoc/junitx/framework/util/HashCodeContractTester.html
http://www.xdweb.net/~dibblego/juni...ework/util/HashCodeContractTesterFactory.html
 
M

Mike

Mike said:
Hey!
[dumb question was here]
Many thanks.

Regards,

Mike

The fact that you are talking about a HashSet implies that you aren't doing
things the right way.
Specifically, you should be handling types with an interface reference, such
as a java.util.Set.
Yes, sorry, sloppy language. I hate it when I do that. The Set is
declared as a Set but instantiated as a HashSet, as you have shown below.
Here is an example:
Set<?> s = new HashSet<?>();

So now you are talking about a Set - the underlying implementation being
[... now-obvious-seeming explanation deleted for brevity ...]
that you meet that contract or the consequences are dire (and often
under-estimate).

(sound of penny, probably dislodged by whacking side of head with palm
of hand, dropping into the mechanism)

Yah, gotcha! D'oh.
Here are some links of interest:
[useful links elided]

Excellent, thank you!

Thanks also to Bill Brogden for the whack the other way.

Regards,

Mike
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top