Comparator.equals()

H

HK

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

Chris Uppal

HK said:
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
 
G

googmeister

Chris said:
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.

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

Ingo R. Homann

Hi,

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.

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
 
C

Chris Uppal

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
 
I

Ingo R. Homann

Hi,

Chris said:
(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
 
T

Thomas Hawtin

Ingo said:
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
 
I

Ingo R. Homann

Hi Thomas,

Thomas said:
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.

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
 
T

Thomas Hawtin

Ingo said:
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
 
P

Patricia Shanahan

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.

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
 
P

Patricia Shanahan

Ingo said:
Hi,




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

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
 
H

HK

Patricia said:
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.
 
I

Ingo R. Homann

Hi,
Good example.


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
 
P

Patricia Shanahan

Ingo said:
Hi,



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

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
 
P

Patricia Shanahan

Patricia said:
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

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
 
D

Dale King

HK said:
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.
 
R

Roedy Green

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.

--
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
 
Joined
Mar 27, 2009
Messages
6
Reaction score
0
自吸泵的常见故障检修/sasami009/blog/item/38c2c13f9abbdcfd828b13d5.html 自吸泵的常见故障检修/sasami009/blog/item/9201cd507090691f367abec9.html 气动隔膜泵的优势/sasami009/blog/item/d1054728398f0ff999250af9.html 潜水排污泵的现状及其发展方向分
sasami009.blog.163.com/blog/static/109755170200911751528918/ 水泵检验标准 sasami009/blog/item/38c2c13f9abbdcfd828b13d5.html blog.china.alibaba.com/blog/sasami009/article/b0-i6379007.html 阀门型号是如何表示的?
blog.china.alibaba.com/blog/sasami009/article/b0-i6378990.html 密封油系统中平衡阀的工作原理
blog.china.alibaba.com/blog/sasami009/article/b0-i6074091.html 为何离心泵启动时要关闭出口阀?
blog.china.alibaba.com/blog/sasami009/article/b0-i6074068.html 磁力泵的工作原理
blog.china.alibaba.com/blog/sasami009/article/b0-i6074036.html 自吸泵安装使用及注意事项
blog.china.alibaba.com/blog/sasami009/article/b0-i6023069.html 水泵检验标准 引言
sasami009.blog.hexun.com/30967267_d.html 排污阀的常见故障及其产生的原因有哪些?
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,678
Members
48,796
Latest member
Greg L.

Latest Threads

Top