With only 52 cards in the deck and with a fairly limited number of comparisons,
maybe the local variable option would be considered better for reasons of
encapsulation and because the Comparator will be automatically marked for
garbage collection once the method has exited. But I'm curious to know under
what kind of circumstances might the overhead of creating a new Comparator
every time compareTo is invoked mean that the instance variable approach
would be preferable. If there are a very large number of objects to be sorted
and sorting occurs regularly, am I going to be wasting memory, or is the fact
that the Comparator contains no instance variables itself relevant?

In general, Comparator implementations belong to a general class of
"stateless" objects. That is, the important thing about them is their
behavior, not their state, so that one instance is as good as any other.
When that's the case, there's simply no benefit to creating multiple
instances. I would create one Comparator and store it in a field. I'd
even be tempted to make it a public static final field, so that others
can choose to use that ordering explicitly when sorting.

Paul Carey wrote:
> When delegating a compareTo method for a playing card to a Comparator, I
> wasn't sure whether to go for the instance variable or local variable
> approach:

Taking your code at face value, the local variable approach is the most
"natural" whereas the instance variable version can be seen as a slightly
convoluted optimisation of the same logic. Looked at that way, then the
standard advice is not to optimise unless you know it makes a useful
difference -- i.e. if you have reason to suppose (say from profiling) that the
comparison is a bottleneck for your application(s) then you would try the
optimised version and measure the difference. If -- note that: *IF* -- it
turned out to be usefully faster then you'd keep the optimisation.

However, in this case I can't see why you are creating a SortByValueThenSuit
object at all -- I'd have expected a Card to know how to compare itself to
another card. If you need Comparators (especially if different contexts use
different comparison policies) then the context would create one that forwards
to the cards' own comparison. There's also nothing to stop you creating a
fixed set of pre-defined Comparator objects (1 or more, embodying whatever
policies are most useful) and assigning them to static variables in the Card
class. (But that's just a convenience, note.)

Then in other code somewhere, we can make a SortedSet of Cards. This example
will use the natural ordering of the Cards defined by the Card.compareTo()
method:
SortedSet inOrder = new TreeSet();
inOrder.add(... a card...);
inOrder.add(... another card...);

Or we could make a reversed SortedSet of Cards using the our own comparator
that sorts in reverse direction:
Comparator comparator =
new Comparator()
{
public int compare(Object o1, Object o2)
{
// NB: arguments are reversed
return (Card)o2->compareTo(o1);
}
};
SortedSet reversed = new TreeSet(comparator);
reversed.add(... a card...);
reversed.add(... another card...);

Share This Page

Welcome to The Coding Forums!

Welcome to the Coding Forums, the place to chat about anything related to programming and coding languages.

Please join our friendly community by clicking the button below - it only takes a few seconds and is totally free. You'll be able to ask questions about coding or chat with the community and help others.
Sign up now!