equals() and persitence

F

Franck

Hi,

Each instance of MyClass should be persisted in table,
MyClass has a private field "key" (long type), with accessors, that is
mapped with the key of the table.

I would like to simplify the use of collections of instances of MyClass
(methods contains(), retains() etc...)

Should I have problems if i redefine equals() and hashcode() on MyClass like
that :

public boolean equals(Object o) {
if (!(o instanceof MyClass))
return false;
MyClass f = (MyClass)o;
return f.getKey() == this.getKey();
}

public int hashcode() {
return (new Long(this.getKey())).intValue()
}

Thanks for your answers
 
T

Thomas Schodt

Franck said:
public boolean equals(Object o) {
if (!(o instanceof MyClass))
return false;

You may want to throw a ClassCastException instead.
MyClass f = (MyClass)o;
return f.getKey() == this.getKey();
}

As MyClass.getKey() returns a long that works.
public int hashcode() {
return (new Long(this.getKey())).intValue()
}

IIRC that's the same as
return (int)this.getKey();
(ie. drop the excess bits).

You could XOR the top and bottom quads.

public int hashcode() {
long k = this.getKey();
return (int)((k>>>32) ^ (k&0xffffffff));
}
 
T

Thomas Schodt

public boolean equals(Object o) {
You may want to throw a ClassCastException instead.

Or not.

AFAICT it's in the contract for Comparable.compareTo()
but not in Object.equals().
 
F

Franck

Thomas said:
You could XOR the top and bottom quads.

public int hashcode() {
long k = this.getKey();
return (int)((k>>>32) ^ (k&0xffffffff));
}

Ca you explain me why ?
Thanks
 
A

Anton Spaans

Thomas Schodt said:
Or not.

AFAICT it's in the contract for Comparable.compareTo()
but not in Object.equals().

I agree.
The JDK String.equals method also just casts the input parameter to a
String... which may throw a ClassCastException. I 'hate' this behavior. I'd
rather see the result that this Object (the String) is not equal to the
input-Object, i.e. it returns false. This is the cause that you can not
store Strings together with other types of Objects into HashMaps or
HashTables.

About your hashCode():
As long as your implementation does not break the general contract of the
method Object.hashCode(). You drop the excess bits, but that is no problem.
See this part of the hashCode() contract:

- It is *not* required that if two objects are unequal according to the
equals(java.lang.Object) method, then calling the hashCode method on each of
the two objects must produce distinct integer results. However, the
programmer should be aware that producing distinct integer results for
unequal objects may improve the performance of hashtables.



-- Anton Spaans.
 
T

Thomas Schodt

Franck said:
Can you explain me why ?

Say you have three object, getKey() returns
0x00001415cafebabe
0x00009265cafebabe
0x00003589cafebabe

(int)getKey() will give
0xcafebabe
0xcafebabe
0xcafebabe

(int)((k>>>32) ^ (k&0xffffffff)) will produce
0xcafeaeab
0xcafe28db
0xcafe8f37

0x1415 ^ 0xbabe is 0xaeab
0x9265 ^ 0xbabe is 0x28db
0x3589 ^ 0xbabe is 0x8f37
 
F

Franck

Thomas said:
Say you have three object, getKey() returns
0x00001415cafebabe
0x00009265cafebabe
0x00003589cafebabe

(int)getKey() will give
0xcafebabe
0xcafebabe
0xcafebabe

(int)((k>>>32) ^ (k&0xffffffff)) will produce
0xcafeaeab
0xcafe28db
0xcafe8f37

0x1415 ^ 0xbabe is 0xaeab
0x9265 ^ 0xbabe is 0x28db
0x3589 ^ 0xbabe is 0x8f37

Thanks sir :)
 
M

Michiel Konstapel

You may want to throw a ClassCastException instead.
I agree.
The JDK String.equals method also just casts the input parameter to a
String... which may throw a ClassCastException. I 'hate' this behavior.
I'd
rather see the result that this Object (the String) is not equal to the
input-Object, i.e. it returns false. This is the cause that you can not
store Strings together with other types of Objects into HashMaps or
HashTables.

What gave you that idea? Here's the code from Sun's 1.4.1 String.java:

public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
// snip comparison code
}
return false;
}

It only casts the argument after an instanceof check.
Michiel
 
A

Anton Spaans

Michiel Konstapel said:
What gave you that idea? Here's the code from Sun's 1.4.1 String.java:

public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
// snip comparison code
}
return false;
}

It only casts the argument after an instanceof check.
Michiel

I was shooting from the hip ** shame on me ** hehehe
but I *do* remember that when putting both Strings and Integers into a
collection, it would throw a classcastexception. And somehow i just remember
it happened in the String.equals() method..... Although, I was not compiling
against jdk1.4. It was against an older version of jdk1.3
I think I was mistaken: The exception is thrown in the compareTo method,
which is part of its contract.
 

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

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top