Design Question re Comparable

Discussion in 'Java' started by Rhino, Feb 23, 2005.

  1. Rhino

    Rhino Guest

    I need a sanity check on a design I am considering.

    I am trying to design a simple class called Range, which subclasses Object.
    I want Range to store a two-element array of Objects that are both of the
    exact same class. However, I only want to store Objects if it is possible to
    determine which of the two is the lower value. Integers have intrinsic order
    so two Integers can obviously can be compared to see which is lower, however
    two JPanels do not have intrinsic order (aside from creation sequence which
    I consider irrelevant for my purposes) so they have no intrinsic order.
    Therefore, I have no problem in creating a Range of Integers but don't want
    to create a Range of JPanels.

    It seems to me that my best approach is to see if the Objects that are
    passed to my Range constructor implement the Comparable interface. If they
    do, I can compare the two Objects in the constructor and determine which is
    the lower value.

    I can use the getInterfaces() method in Class to determine the interfaces
    implemented by the incoming Objects and then use the compareTo() method
    defined for that class to find out which is lower, then store it as a class
    variable called 'lowValue'; the other Object gets stored in 'highValue'.
    Then I can write a between() method to determine if a third value is within
    the Range defined by the two Objects in the Range.

    Is this design basically sound?

    Followup question: If this design is sound, how do I compare the actual
    values of the Objects? In my constructor, I know that they belong to the
    same class and that the class implements Comparable but how do I actually
    see which is lower? I have to cast them from Object to their actual class
    and then do compareTo() right? If so, how do I cast them from Object to
    their actual class? I know the following does NOT compile because the
    firstObject.getClass() is not an actual class name, just something that
    resolves to a class name, which isn't good enough for the compiler:

    if ( ((firstObject.getClass()) firstObject).compareTo(
    ((secondObject.getClass()) secondObject)) > 0) {
    }

    So how do I compare the two values to see which is lower? I assume there is
    some standard idiom that will let me do this but I don't know what it is.

    --
    Rhino
    ---
    rhino1 AT sympatico DOT ca
    "There are two ways of constructing a software design. One way is to make it
    so simple that there are obviously no deficiencies. And the other way is to
    make it so complicated that there are no obvious deficiencies." - C.A.R.
    Hoare
    Rhino, Feb 23, 2005
    #1
    1. Advertising

  2. Rhino

    Eric Sosman Guest

    Rhino wrote:
    > I need a sanity check on a design I am considering.
    >
    > I am trying to design a simple class called Range, which subclasses Object.
    > I want Range to store a two-element array of Objects that are both of the
    > exact same class. However, I only want to store Objects if it is possible to
    > determine which of the two is the lower value. Integers have intrinsic order
    > so two Integers can obviously can be compared to see which is lower, however
    > two JPanels do not have intrinsic order (aside from creation sequence which
    > I consider irrelevant for my purposes) so they have no intrinsic order.
    > Therefore, I have no problem in creating a Range of Integers but don't want
    > to create a Range of JPanels.
    >
    > It seems to me that my best approach is to see if the Objects that are
    > passed to my Range constructor implement the Comparable interface. If they
    > do, I can compare the two Objects in the constructor and determine which is
    > the lower value.
    >
    > I can use the getInterfaces() method in Class to determine the interfaces
    > implemented by the incoming Objects and then use the compareTo() method
    > defined for that class to find out which is lower, then store it as a class
    > variable called 'lowValue'; the other Object gets stored in 'highValue'.
    > Then I can write a between() method to determine if a third value is within
    > the Range defined by the two Objects in the Range.
    >
    > Is this design basically sound?


    The design is sound, but you're working far too hard.
    Just define the Range constructor to take two Comparable
    objects:

    public Range(Comparable x, Comparable y)

    Now, this isn't *quite* enough, because two classes that
    implement Comparable might not be comparable to each other:
    if `x' is a String and `y' is an Integer, both implement
    Comparable but the attempt to use either's compareTo()
    method on the other will fail. However, since you're
    planning to use compareTo() anyhow to discover how `x'
    and `y' map to `lowValue' and `highValue', any such problem
    will be detected immediately: the compareTo() method will
    throw an exception and the constructor will exit.

    (Advanced and optional topic: See also Comparator for
    a way to compare non-Comparable objects.)

    > Followup question: If this design is sound, how do I compare the actual
    > values of the Objects? In my constructor, I know that they belong to the
    > same class and that the class implements Comparable but how do I actually
    > see which is lower? I have to cast them from Object to their actual class
    > and then do compareTo() right?


    No cast is needed; just use compareTo(). That's what
    polymorphism is all about.

    Forgive me for saying so, but several of your questions
    have a strong "beginner flavor" about them, which suggests
    that they probably belong in comp.lang.java.help rather than
    here. It also suggests that you need to drag out your Java
    textbook again and re-read it; something didn't "take" the
    first time around.

    --
    Eric Sosman, Feb 23, 2005
    #2
    1. Advertising

  3. Rhino

    Rhino Guest

    "Eric Sosman" <> wrote in message
    news:cvifd2$46p$...
    >
    >
    > Rhino wrote:
    > > I need a sanity check on a design I am considering.
    > >
    > > I am trying to design a simple class called Range, which subclasses

    Object.
    > > I want Range to store a two-element array of Objects that are both of

    the
    > > exact same class. However, I only want to store Objects if it is

    possible to
    > > determine which of the two is the lower value. Integers have intrinsic

    order
    > > so two Integers can obviously can be compared to see which is lower,

    however
    > > two JPanels do not have intrinsic order (aside from creation sequence

    which
    > > I consider irrelevant for my purposes) so they have no intrinsic order.
    > > Therefore, I have no problem in creating a Range of Integers but don't

    want
    > > to create a Range of JPanels.
    > >
    > > It seems to me that my best approach is to see if the Objects that are
    > > passed to my Range constructor implement the Comparable interface. If

    they
    > > do, I can compare the two Objects in the constructor and determine which

    is
    > > the lower value.
    > >
    > > I can use the getInterfaces() method in Class to determine the

    interfaces
    > > implemented by the incoming Objects and then use the compareTo() method
    > > defined for that class to find out which is lower, then store it as a

    class
    > > variable called 'lowValue'; the other Object gets stored in 'highValue'.
    > > Then I can write a between() method to determine if a third value is

    within
    > > the Range defined by the two Objects in the Range.
    > >
    > > Is this design basically sound?

    >
    > The design is sound, but you're working far too hard.
    > Just define the Range constructor to take two Comparable
    > objects:
    >
    > public Range(Comparable x, Comparable y)
    >

    D'OH!

    I had a feeling there was an easier way than what I was doing... ;-)

    > Now, this isn't *quite* enough, because two classes that
    > implement Comparable might not be comparable to each other:
    > if `x' is a String and `y' is an Integer, both implement
    > Comparable but the attempt to use either's compareTo()
    > method on the other will fail. However, since you're
    > planning to use compareTo() anyhow to discover how `x'
    > and `y' map to `lowValue' and `highValue', any such problem
    > will be detected immediately: the compareTo() method will
    > throw an exception and the constructor will exit.
    >

    Yes, I had that worry in the back of my mind; thanks for explaining how to
    handle it.

    > (Advanced and optional topic: See also Comparator for
    > a way to compare non-Comparable objects.)
    >

    Okay....

    > > Followup question: If this design is sound, how do I compare the actual
    > > values of the Objects? In my constructor, I know that they belong to the
    > > same class and that the class implements Comparable but how do I

    actually
    > > see which is lower? I have to cast them from Object to their actual

    class
    > > and then do compareTo() right?

    >
    > No cast is needed; just use compareTo(). That's what
    > polymorphism is all about.
    >

    Again, I assumed there was an easier way than what I was doing. It felt
    kludgey to cast the objects before comparing them but I couldn't compare to
    straight Objects directly so I wasn't sure how to proceed. It never occurred
    to me to pass two Comparables to the constructor; I thought you could only
    pass classes to a constructor, not interfaces.

    > Forgive me for saying so, but several of your questions
    > have a strong "beginner flavor" about them, which suggests
    > that they probably belong in comp.lang.java.help rather than
    > here. It also suggests that you need to drag out your Java
    > textbook again and re-read it; something didn't "take" the
    > first time around.
    >

    The main textbook I used was 1001 Java Programmer's Tips, written back in
    the Java 1.0 days; it's not what most people would call strong on giving OO
    design concepts ;-)

    That's why I've enjoyed this discussion; I've already gotten some ideas for
    good OO and Java design books. I really need to fill in a lot of my
    conceptual gaps ;-)

    Rhino
    Rhino, Feb 23, 2005
    #3
  4. Rhino

    Chris Uppal Guest

    Eric Sosman wrote:

    > The design is sound, but you're working far too hard.
    > Just define the Range constructor to take two Comparable
    > objects:
    >
    > public Range(Comparable x, Comparable y)
    >
    > Now, this isn't *quite* enough, because two classes that
    > implement Comparable might not be comparable to each other:


    If Rhino wants an additional sanity check (I wouln't bother myself, but...)
    then doing

    x.compareTo(y);
    y.compareTo(x);

    in the constuctor would catch most cases where the end-points didn't agree on
    how to compare things.

    -- chris
    Chris Uppal, Feb 23, 2005
    #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. Replies:
    5
    Views:
    6,868
  2. steve

    implementing comparable

    steve, Nov 16, 2004, in forum: Java
    Replies:
    2
    Views:
    456
    steve
    Nov 18, 2004
  3. Bergholt

    Generics and Comparable

    Bergholt, Nov 27, 2004, in forum: Java
    Replies:
    3
    Views:
    6,032
    Bergholt
    Nov 30, 2004
  4. Manuel Kasten
    Replies:
    5
    Views:
    72
    Manuel Kasten
    Nov 10, 2005
  5. Replies:
    3
    Views:
    84
Loading...

Share This Page