greeting everyone,
I have a problem with sets, according to the API documentation
Class TreeSet<E>
---------------------------
public boolean add(E e)
Adds the specified element to this set if it is not already
present. More formally, adds the specified element e to this set if the
set contains no element e2 such that (e==null ? e2==null :
e.equals(e2)). If this set already contains the element, the call
leaves the set unchanged and returns false.
new I have this code:
-----------------------------
Set identities = new java.util.TreeSet<Identity>();
System.out.println(id1.equals(id2));
System.out.println(identities.add(id1));
System.out.println(identities.add(id2));
output is:
------------
true
true
true
where's the problem???
regards,
Bassel
Robert Klemme - 21 Sep 2006 11:12 GMT
> greeting everyone,
>
[quoted text clipped - 24 lines]
>
> where's the problem???
You probably did not implement class Identity properly. You need to
implement compareTo() for a TreeSet. For a HashSet you need equals()
and hash(). You probably should do all of these methods for
completeness reasons.
Kind regards
robert
bassel - 21 Sep 2006 11:27 GMT
> implement compareTo() for a TreeSet. For a HashSet you need equals()
> and hash().
Ok, I did, and the problem is gone but may I ask why does the
documentation mention
"
adds the specified element e to this set if the
set contains no element e2 such that (e==null ? e2==null :
e.equals(e2))."
when it should be
------------------------
"
adds the specified element e to this set if the
set contains no element e2 such that (e==null ? e2==null :
e.compareTo(e2)==0)."
thanks for help
Bassel
Hendrik Maryns - 21 Sep 2006 11:37 GMT
bassel schreef:
>> implement compareTo() for a TreeSet. For a HashSet you need equals()
>> and hash().
[quoted text clipped - 13 lines]
> set contains no element e2 such that (e==null ? e2==null :
> e.compareTo(e2)==0)."
If a class is ordered, i.e. it implements Comparable, then it should be
‘consistent with equals’, as you can read in the API for Comparable:
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Comparable.html
H.

Signature
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
http://aouw.org
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
Michael Rauscher - 21 Sep 2006 11:41 GMT
bassel schrieb:
>> implement compareTo() for a TreeSet. For a HashSet you need equals()
>> and hash().
[quoted text clipped - 15 lines]
>
> thanks for help
From the TreeSet API:
"Note that the ordering maintained by a set (whether or not an explicit
comparator is provided) must be consistent with equals if it is to
correctly implement the Set interface. (See Comparable or Comparator
for a precise definition of consistent with equals.) This is so because
the Set interface is defined in terms of the equals operation, but a
TreeSet instance performs all key comparisons using its compareTo (or
compare) method, so two keys that are deemed equal by this method are,
from the standpoint of the set, equal. The behavior of a set is
well-defined even if its ordering is inconsistent with equals; it just
fails to obey the general contract of the Set interface."
Bye
Michael
bassel - 21 Sep 2006 11:57 GMT
> TreeSet instance performs all key comparisons using its compareTo (or
> compare) method, so two keys that are deemed equal by this method are,
> from the standpoint of the set, equal. The behavior of a set is
> well-defined even if its ordering is inconsistent with equals; it just
> fails to obey the general contract of the Set interface."
it's clear now, TreeSet deals with only compareTo and my class was like
that
--------------------------------
/**
*
*/
package test;
/**
* @author Administrator
*
*/
public class Identity implements Comparable{
private String name;
private long id;
public void setName(String name){
this.name = name;
}
public void setId(long id){
this.id = id;
}
public String getName(){
return this.name;
}
public double getId(){
return this.id;
}
public boolean equals(Object obj){
System.out.println("equals says: I'm invoked");
try{
Identity otherIdentity = (Identity)obj;
return (this.name.equals(otherIdentity.name));
}catch(ClassCastException e){
return false;
}
}
public int compareTo(Object obj){
System.out.println("compareTo says: I'm invoked");
Identity otherIdentity = (Identity)obj;
if (this.id > otherIdentity.getId())
return 1;
else if (this.id < otherIdentity.getId())
return -1;
else
return 0;
}
public int hashCode(){
return name.hashCode();
}
}
-----------------------------------------
so the compareTo() was not consistent with equals().
thank you,
Bassel
Chris Brat - 21 Sep 2006 11:29 GMT
Hi,
Heres and example I did - the results are :
true
true
false
[A$Identity@1cdeff]
To be of any actual use you have to correct the compare and equals
methods.
Regards,
Chris
public class A {
private static class IdentityComparator implements Comparator{
public int compare(Object a, Object b){
// implement this correctly
return 0; // as a test this always indicates equality
}
}
private static class Identity {
public boolean equals(Object obj){
// implement this correctly
return true; // as a test this always indicates equality
}
}
public static void main(String[] args){
Set identities = new java.util.TreeSet<Identity>(new
IdentityComparator());
Identity id1 = new Identity();
Identity id2 = new Identity();
System.out.println(id1.equals(id2));
System.out.println(identities.add(id1));
System.out.println(identities.add(id2));
System.out.println(identities);
}
}
> greeting everyone,
>
[quoted text clipped - 27 lines]
> regards,
> Bassel
Mark Jeffcoat - 21 Sep 2006 15:57 GMT
> new I have this code:
> -----------------------------
[quoted text clipped - 10 lines]
>
> where's the problem???
I can think of a couple of ways this could go
wrong:
1. TreeSet keeps the set ordered, and may be using
compareTo==0 instead of equals() to decide if the
identity is already present. If your compareTo()
definition is somehow inconsistent with equals,
this won't work.
If that's what's happening, you should get the
right answer if your demo works for a HashSet().
2. The HashSet test fails if you've got a hashCode()
that's inconsistent with equals(). Make sure
you've got that right--if you're not sure, just
define hashCode() to return 0 for now.
3. If it's still not working, you've probably
declared equals() incorrectly. Make sure you're
overriding equals(Object), not equals(Identity).
One other problem: your declaration
Set s = new TreeSet<Identity>();
isn't doing what you probably think it is. You
won't be prevented by the compiler from adding
arbitrary Objects to s.
To ask the compiler for help in making sure you
only add Identities to the collection, you need
Set<Identity> s = new TreeSet<Identity>();
or at least (my preferred form)
Set<Identity> s = new TreeSet();

Signature
Mark Jeffcoat
Austin, TX