Re: Set and .equals() semantics
Rex Mottram <rexm@not.here> writes:
I don't believe anyone has used the word "must" until now. No one has demanded
anything (and there's been no "whining" either).
What are you on about? "Whining"? Where'd that come from? What do "demands"
have to do with anything? You lost me there.
The word "must" needn't have been used yet. The point under contention was
that Set should sport a find() method. In order for that suggestion to be
implemented, Set must be changed, therefore the "must" was corollate to the
suggestion. There is no way to implement a change to the definition of Set
without changing the definition of Set.
I think this is really about aesthetics. You've stated your aesthetic
position; the alternate view is that "The object is mine. I made it. I
put it in the set, and now you're telling me I can't get it back out?"
It is not about aesthetics. That is a straw-man argument, as my comments were
based on pragmatics, not aesthetics, and on the correctness of equals()
semantics, as Lasse Reichstein Nielsen so ably elucidated. To argue on the
basis of aesthetics is immaterial.
Lasse Reichstein Nielsen wrote:
It's your object. You already have it.
That's the secret to the whole shebang.
LRN:
You put it into a Set that uses the equals() method on your object
to distinguish objects. To use a find method, you need an object
that is *equal* to the one in the Set. From the Set's perspective,
that proves that you already have it.
A find() method would just return its argument if contains() were true, as LRN
points out.
RM:
I see nothing in the mathematical or natural-language definitions of
"set" to the effect that one of its properties is that once you put it
in you lose access to it.
I see nothing in the definition of java.util.Set that implies that property,
either.
LRN:
Mathematical sets don't have equal elements that can also be
distinguished.
Nor do java.util.Sets.
RM:
We have gone well beyond my (the OP's) specific implementation, BTW,
so let's not critique that anymore. The question on the table is "why
is it offensive to Set semantics to allow me to get back what I have
placed in it?"
"offensive"? Strange choice of words. The problem isn't offensiveness, it's
incompatibility. A find() method that used a different definition of equals()
than contains() would be contrary to every other aspect of Set semantics. A
find() method that uses the same definition as contains() adds zero utility to
the Set interface. Aesthetics, offensiveness and other colorful
personifications lead one astray from the technical matters that truly matter.
As LRN says, the suggestion is awry
Because it breaks the abstraction of the equals() method, the one thing
that collections are based on.
In fact, such a thing is offensive, according to the aesthetics of utility and
semantic coherence.
RM:
Contains()
is required to *behave* as if equals() had been called; true, it is
not required to actually *call* it but one would have to tiptoe pretty
carefully to construct a case where you could do one reliably without
the other.
LRN:
Take EnumSet. It doesn't store the Enum values, just a BitSet of
their ordinals.
Tiptoe, indeed. Reaching all the way into the fundamental Java API
(java.util, not even javax.**).
However, to implement iterator() and toArray() the Set needs to
be able to, at least, recreate its contents.
And that is done according to equals(), not ==.
find() is not an appropriate method for Set. QED.
public T find( T exemplar )
{
return (contains( exemplar )? exemplar : null);
}
--
Lew