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 / September 2006

Tip: Looking for answers? Try searching our database.

problem with Sets

Thread view: 
bassel - 21 Sep 2006 10:56 GMT
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



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



©2008 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.