Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / July 2005

Tip: Looking for answers? Try searching our database.

Comparator.equals()

Thread view: 
HK - 27 Jul 2005 10:08 GMT
Does anyone have an idea why the interface
java.util.Comparator explicitly mentions the
equals() method which is anyway defined for
each Object?

The docs say:
  Note that it is always safe not to override
  Object.equals(Object). However, overriding
  this method may, in some cases, improve
  performance by allowing programs to determine
  that two distinct Comparators impose the same order.

Well, but why would I generate a large number of
Comparators which do exactly the same? My typical
comparator looks rather like

public static final Comparator cmpBlaOnBlifield = new Comparator() {
 // run comparison of Bla objects based on field bli
}

 Harald.
Chris Uppal - 27 Jul 2005 11:18 GMT
> Does anyone have an idea why the interface
> java.util.Comparator explicitly mentions the
> equals() method which is anyway defined for
> each Object?

Somewhat tenuous, but possibly it's intended to allow (or encourage) designs
where it is possible for code to determine whether a given collection is
already sorted in the order that it wants, and thus avoid the expense of
resorting needlessly.

   -- chris
googmeister@gmail.com - 27 Jul 2005 11:45 GMT
> > Does anyone have an idea why the interface
> > java.util.Comparator explicitly mentions the
[quoted text clipped - 5 lines]
> already sorted in the order that it wants, and thus avoid the expense of
> resorting needlessly.

Sounds reasonable.

But why put equals() in the Comparator interface? It's redundant
since every Object already promises to have an equals() method.
The Comparable interface doesn't include an equals() method
even though the Javadocs recommend you define one that is
consistent with compareTo. I don't see this as a big issue, but
just wondering if there's a good rule for when to include a
redundant method in an interface.
Ingo R. Homann - 27 Jul 2005 12:32 GMT
Hi,

> But why put equals() in the Comparator interface? It's redundant
> since every Object already promises to have an equals() method.
[quoted text clipped - 3 lines]
> just wondering if there's a good rule for when to include a
> redundant method in an interface.

I guess this is only done to indicate that it might be a good idea to
really implement this method. It is redundant, you're right.

Ciao,
Ingo
Chris Uppal - 27 Jul 2005 13:07 GMT
> But why put equals() in the Comparator interface? It's redundant
> since every Object already promises to have an equals() method.

At a guess: because that's the only way they could get the comment to appear in
the JavaDoc.

More serious point: one way of thinking of interfaces is that they are
primarily a documentary feature (the fact that the compiler -- or more
accurately the type-checker -- understands them can be seen as a
machine-assisted special-case of their more general documentary role).  As
such, if an interface qualifies or extends the contract required/expected by
users of objects implementing it, then that fact should appear in the interface
specification.  Since interfaces mostly only "document" methods, it seems
natural to duplicate a method from a parent interface (or from
java.lang.Object) in the interface, if that interfaces modifies the more
general contract for the method -- even if that extension isn't something that
can be expressed in Java except as a comment.

   interface Sane
   {
       /**
       * Blah blah blah...
       */
       String getName();
   }

   interface Insane
   extends Sane
   {
       /**
       * Returns null on Thursdays.
       */
       String getName();
   }

(But I should say that I'm not convinced that Comparator.equals() is a good
example of this kind of reasoning -- I would have put that kind of "design
note" into the class comment, if anywhere.)

   -- chris
Ingo R. Homann - 27 Jul 2005 13:44 GMT
Hi,

> (But I should say that I'm not convinced that Comparator.equals() is a good
> example of this kind of reasoning -- I would have put that kind of "design
> note" into the class comment, if anywhere.)

By the way: Can anyone imagine a consistent implementation of
Comparator#equals except the inherited one from java.lang.Object?

I mean, (without doing some *really* difficult bytecode-analysis) it
should be *impossible* to detect if another Comparator does exactly the
same as the Comparator I have implemented. Or am I wrong?

Ciao,
Ingo
Thomas Hawtin - 27 Jul 2005 14:07 GMT
> By the way: Can anyone imagine a consistent implementation of
> Comparator#equals except the inherited one from java.lang.Object?
>
> I mean, (without doing some *really* difficult bytecode-analysis) it
> should be *impossible* to detect if another Comparator does exactly the
> same as the Comparator I have implemented. Or am I wrong?

As the docs say is is always safe not to override it. All you need to
promise is that two Comparators that order differently are not equal.
The reverse implication is not specified.

Tom Hawtin
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

Ingo R. Homann - 27 Jul 2005 14:26 GMT
Hi Thomas,

>> By the way: Can anyone imagine a consistent implementation of
>> Comparator#equals except the inherited one from java.lang.Object?
[quoted text clipped - 6 lines]
> promise is that two Comparators that order differently are not equal.
> The reverse implication is not specified.

I know, but that does not answer my question: Of course, it is OK to
override equals so that it always returns false (like e.g. it is OK to
override hashCode so that it always returns 0), but what would a
*better* implementation look like?

Ciao,
Ingo
Thomas Hawtin - 27 Jul 2005 14:37 GMT
> I know, but that does not answer my question: Of course, it is OK to
> override equals so that it always returns false (like e.g. it is OK to

Not always false. a.equals(a) must always be true (for a != null).

> override hashCode so that it always returns 0), but what would a
> *better* implementation look like?

final public MyComparator implements java.util.Comparator<Tea> {
    private int someState;
    ...
    public int compare(Tea o1, Tea o2) {
        ...
    }
    @Override
    public int hashCode() {
        retuen someState;
    }
    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (!(obj instanceof MyComparator)) {
            return false;
        }
        MyComparator other = (MyComparator)obj;
        return this.someState = other.someState;
    }

Tom Hawtin
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

Patricia Shanahan - 27 Jul 2005 15:00 GMT
> Hi,
>
[quoted text clipped - 13 lines]
> Ciao,
> Ingo

Suppose I have a class that represents a row of a database or table.
Each column is of a Comparable type. There is Comparator-implementing
class, RowComparator, whose constructor takes as parameter a list of
column headings to use as sort keys. A RowComparator compares rows using
the columns in order of appearance in the list.

Two instances of RowComparator are equal, in the sense specified in the
Comparator interface, if, and only if, their column heading lists are equal:

public final class RowComparator implements Comparator{
...
  List sortKeys;
...
  public boolean equals(Object other){
    if(!(other instanceof RowComparator){
      return false;
    }
    return sortKeys.equals(((RowComparator)other).sortKeys);
  }
...
}

The Table could cache sort results, indexed by RowComparator, and return
as sort result the result of a previous sort using an equal RowComparator.

Patricia
HK - 27 Jul 2005 15:09 GMT
> Suppose I have a class that represents a row of a database or table.
> Each column is of a Comparable type. There is Comparator-implementing
> class, RowComparator, whose constructor takes as parameter a list of
> column headings to use as sort keys. A RowComparator compares rows using
> the columns in order of appearance in the list.

Good example.

> The Table could cache sort results, indexed by RowComparator, and return
> as sort result the result of a previous sort using an equal RowComparator.

I would probably have made sure not to generate equal RowComparator
instances in the first place by caching the request rather than
the resulting Comparator. But I agree that this may often be
cumbersome or even impossible.

 Thanks,
 Harald.
Ingo R. Homann - 27 Jul 2005 16:30 GMT
Hi,

>>Suppose I have a class that represents a row of a database or table.
>>Each column is of a Comparable type. There is Comparator-implementing
[quoted text clipped - 9 lines]
> I would probably have made sure not to generate equal RowComparator
> instances in the first...

That is exactly what I meant. Wouldn't it be useful to implement a
static method MyComparator.getInstance(param) that always returns the
same Comparator-instance for the same param?

And when another Comparator (another implementation) is instantiated,
which by coincidence does (semantically) the same, I will always be
unable to recoginze, that it does the same!

Ciao,
Ingo
Patricia Shanahan - 27 Jul 2005 18:18 GMT
> Hi,
>
[quoted text clipped - 23 lines]
> Ciao,
> Ingo

That is one option, but it is not the only option. Generally, there are
two ways to handle logical equality between objects:

1. Override equals and hashCode so that logically equal objects are
recognized as being equal.

2. Manipulate object construction so that at most one instance exists
for any given logical value, and use object identity as a surrogate for
logical equality.

Both seem valid to me. One puts the work of recognizing logical equality
in the equals and hashCode methods, the other puts it in the
construction. The first is much more direct - you can find out how
equals will behave by reading its documentation, without having to look
into how objects are constructed.

In both cases, you need to give some thought to subclasses (I ducked the
issue in my example by making the class final).

Patricia
Patricia Shanahan - 27 Jul 2005 18:32 GMT
>> Hi,
>>
[quoted text clipped - 46 lines]
>
> Patricia

There is one situation in which it is a lot less work, or even
essential, to use the .equals approach. Suppose when the class was
designed there was no interest in logical equality, and it was designed
with a simple constructor. Later, you decide you need logical equality.

Using the first approach, the changes are localized to the RowComparator
class. Using the second approach, each constructor call has to be
changed to the corresponding static factory method call.

Patricia
Patricia Shanahan - 27 Jul 2005 14:48 GMT
>>>Does anyone have an idea why the interface
>>>java.util.Comparator explicitly mentions the
[quoted text clipped - 15 lines]
> just wondering if there's a good rule for when to include a
> redundant method in an interface.

Putting an Object method in an interface declaration allows Javadoc
declaration of the meaning equals is required to have in classes that
implement the interface.

For another example, see the List interface. A List-implementing class
should not use the Object equals, because it does not conform to the
List contract for equals.

The rule I follow, that seems to be the one used in the API, is to put
an object method in an interface declaration if, and only if, there is a
different contract from the immediate superinterface or Object.

Patricia
Dale King - 28 Jul 2005 04:48 GMT
> Does anyone have an idea why the interface
> java.util.Comparator explicitly mentions the
> equals() method which is anyway defined for
> each Object?

Because Comparator is adding additional constraints onto the equals method.

Signature

 Dale King

Roedy Green - 28 Jul 2005 06:30 GMT
On 27 Jul 2005 02:08:23 -0700, "HK" <pifpafpuf@gmx.de> wrote or quoted

>Does anyone have an idea why the interface
>java.util.Comparator explicitly mentions the
>equals() method which is anyway defined for
>each Object?

I guess they are just trying to remind you to implement it. IT
compares Comparators, not Strings or whatever you are sorting.

Signature

Bush crime family lost/embezzled $3 trillion from Pentagon.
Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm

Canadian Mind Products, Roedy Green.
See http://mindprod.com/iraq.html photos of Bush's war crimes



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.