Re: Help with Deck of cards assignment and getting it to deal...
On 8/3/2014 5:19 PM, Jeff Higgins wrote:
On 08/03/2014 04:49 PM, Eric Sosman wrote:
On 8/3/2014 3:26 PM, Arne Vajh?j wrote:
[...]
I must admit that I can not follow you.
The fact that different games may use a different ordering is
not an argument against Comparable<>.
Comparable<> is not the one and only ordering. Comparable<> is
just the natural ordering. It is perfectly valid to have a
Comparable<> with the natural ordering and a bunch of
Comparator<> to handle the context specific orderings.
Although one could select different Comparators for different
games -- one for Ace-low, say, and another for Ace-high -- there
is no way a Comparator could work for "Ace-either" games like Poker
(and certainly not for "Ace-both" games like high-low Poker!). Like
Comparable, Comparator reflects a _total ordering_ on the objects it
compares, and a total ordering must be transitive:
If X < Y and Y < Z then X < Z, for all X,Y,Z.
In Poker, one can have
Ace < Five and Five < Ten but Ten < Ace
... violating transitivity, so the ranks do not follow a total order.
In my proposed interface Ace is a valid Rank but Five and Five is not.
What rank, then, does the Five of Spades have?
In my proposed interface I cannot see where any contract is broken by
run time variation of the natural ordering of the Rank. Sure, comparing
one Rank object at different times or places and getting different
results might seem odd but not wrong. I may be though. Please correct
me if this is the case.
See the Javadoc for Comparable. The very first sentence reads:
"This interface imposes a total ordering on the objects of each
class that implements it."
The Javadoc for Comparator begins with a sentence fragment rather than
with a sentence, but that fragment reads:
"A comparison function, which imposes a _total ordering_ on some
collection of objects."
Observe further that both interfaces expose the imposed total order
by way of pairwise comparisons; neither interface has a method to sort
N objects (much less "all" objects) simultaneously. Therefore, when we
try to investigate the imposed total order we must do so by comparing
one pair at a time. So: We discover X < Y *now* and Y < Z *next*, and
by virtue of the total order we can conclude X < Z *hereafter*. We
don't even need to make the comparison; we already know the answer --
*if* there's a total ordering. If we make the comparison anyhow and
discover Z < X we must conclude that there is *not* a total ordering,
and that the Comparable or Comparator does not behave as advertised.
Lest you think this is all "theoretical" or something, consider how
Arrays.binarySearch() works: It compares the sought key S to some object
in the array, discovers S < X, and eliminates all elements >= X from
further consideration. Is it justified in eliminating those elements?
Only if the total ordering holds.
If you don't like arrays and prefer collections, consider TreeMap:
Can you explain how a TreeMap could work in the absence of a total
ordering? Or how it could work if the ordering were somehow changed
*after* some affected keys had already been inserted? "Ah, the sought
key compares greater than the key of the root node, so I'll follow the
right branch of the tree -- oh, wait, maybe I should follow both
branches, just in case the ordering has changed ..."
One could (as Arne Vajh?j pointed out) implement Comparable anyhow
for Ranks, Suits, Cards, and Hands, and one could implement it in a way
that satisfies all Java's expectations. But such Comparables would not
be able to capture the rules of popular card games, because those rules
do not always admit of a total ordering. I do not deny that Comparable
could be implemented, but I maintain that
> Your Card class will be more easily used if it implement the
> java.lang.Comparable<T> interface
is false for many card games.
--
esosman@comcast-dot-net.invalid