Instance Variable vs Local Variable

Discussion in 'Java' started by Paul Carey, Dec 3, 2003.

  1. Paul Carey

    Paul Carey Guest

    Hi

    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:

    public class Card implements Comparable
    {
    static class SortByValueThenSuit implements Comparator
    {
    public int compare(Object o1, Object o2)
    {
    ...
    }
    }

    // local variable approach
    public int compareTo(Object o)
    {
    return new SortByValueThenSuit().compare(this, o);
    }


    // instance variable approach
    private SortByValueThenSuit sorter = new SortByValueThenSuit();
    public int compareTo(Object o)
    {
    return sorter.compare(this, o);
    }
    }

    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?

    Many thanks

    Paul
     
    Paul Carey, Dec 3, 2003
    #1
    1. Advertising

  2. Paul Carey

    VisionSet Guest

    "Paul Carey" <> wrote in message
    news:...
    > Hi
    >
    > 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:
    >
    > public class Card implements Comparable
    > {
    > static class SortByValueThenSuit implements Comparator
    > {
    > public int compare(Object o1, Object o2)
    > {
    > ...
    > }
    > }
    >
    > // local variable approach
    > public int compareTo(Object o)
    > {
    > return new SortByValueThenSuit().compare(this, o);
    > }
    >
    >
    > // instance variable approach
    > private SortByValueThenSuit sorter = new SortByValueThenSuit();
    > public int compareTo(Object o)
    > {
    > return sorter.compare(this, o);
    > }
    > }


    Instantiation is always expensive, don't do it more often than neccessary.
    I see no value in the local variable approach for any number of comparisons,
    unless you retrieve the same instance each time.

    --
    Mike W
     
    VisionSet, Dec 3, 2003
    #2
    1. Advertising

  3. Paul Carey

    Chris Smith Guest

    Paul Carey wrote:
    > Hi
    >
    > 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:
    >
    >
    > // local variable approach
    > public int compareTo(Object o)
    > {
    > return new SortByValueThenSuit().compare(this, o);
    > }
    >
    >
    > // instance variable approach
    > private SortByValueThenSuit sorter = new SortByValueThenSuit();
    > public int compareTo(Object o)
    > {
    > return sorter.compare(this, o);
    > }


    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.

    --
    www.designacourse.com
    The Easiest Way to Train Anyone... Anywhere.

    Chris Smith - Lead Software Developer/Technical Trainer
    MindIQ Corporation
     
    Chris Smith, Dec 3, 2003
    #3
  4. Paul Carey

    Chris Uppal Guest

    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.)

    I.e. something like (completely untested)

    class Card implements Comparable
    {
    //...

    /** implements "standard" comparison by value then suite */
    public int
    compareTo(Object o)
    {
    Card other = (Card)o.
    if (other.value() < this.value())
    return -1;
    if (other.value() > this.value())
    return +1;
    if (other.suite() < this.suite())
    return -1;
    if (other.suite() > this.suite())
    return +1;
    return 0;
    }

    // you may want to override equals() & hash() too
    }


    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...);

    -- chris
     
    Chris Uppal, Dec 3, 2003
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jerry
    Replies:
    5
    Views:
    32,972
    Roedy Green
    Aug 6, 2005
  2. Patrick Hoffmann
    Replies:
    3
    Views:
    2,854
    Christian Jan├čen
    Aug 8, 2003
  3. Gerry Sutton
    Replies:
    1
    Views:
    559
    Peter Otten
    Apr 16, 2005
  4. David Garamond
    Replies:
    5
    Views:
    263
    Ara.T.Howard
    Jun 8, 2004
  5. Leon Bogaert
    Replies:
    19
    Views:
    341
    Robert Klemme
    Mar 23, 2008
Loading...

Share This Page