You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Michael Qiu (JIRA)" <ji...@apache.org> on 2009/01/13 03:13:00 UTC

[jira] Created: (COLLECTIONS-311) isEqualSet method in SetUtils could rehash the two input sets before it does the containsAll comparison

isEqualSet method in SetUtils could rehash the two input sets before it does the containsAll comparison
-------------------------------------------------------------------------------------------------------

                 Key: COLLECTIONS-311
                 URL: https://issues.apache.org/jira/browse/COLLECTIONS-311
             Project: Commons Collections
          Issue Type: Improvement
          Components: Set
    Affects Versions: 3.2
            Reporter: Michael Qiu


Hey Guys

I had an interesting problem recently where I was comparing 2 sets and the equals method was returning false... maybe it might be easier to understand if I explain using pseudo code:
{code}
set1.equals(set2) = false
set1.get(0).equals(set2.get(0)) = true
set1.get(1).equals(set2.get(1)) = true
set1.get(0).hashCode() == set2.get(0).hashCode() = true
set1.get(1).hashCode() == set2.get(1).hashCode() = true
{code}
So, objects in the two sets are equals, the hashCode of the objects in the two sets are equals, however the equals comparison at the set level was not equals.  

After some time, we figured out that the problem was that the object inside the set was getting modified after it was put into the set.  So the new hashCode of the object has changed.  However the bucket of the set that it's in hasn't changed.  When another piece of code calls the contains method, it looks for the equivalent object in a bucket according to the new hashCode.  When it doesn't find it, and it returns false.  

I would like to suggest that the SetUtils.isEqualSet method rehashes contents of the sets given in the parameters before it does the containsAll comparison to avoid the problem caused by this scenario.  


-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Closed: (COLLECTIONS-311) isEqualSet method in SetUtils could rehash the two input sets before it does the containsAll comparison

Posted by "Henri Yandell (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/COLLECTIONS-311?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Henri Yandell closed COLLECTIONS-311.
-------------------------------------

    Resolution: Won't Fix

Marking as WONTFIX per Stephen's comments.

> isEqualSet method in SetUtils could rehash the two input sets before it does the containsAll comparison
> -------------------------------------------------------------------------------------------------------
>
>                 Key: COLLECTIONS-311
>                 URL: https://issues.apache.org/jira/browse/COLLECTIONS-311
>             Project: Commons Collections
>          Issue Type: Improvement
>          Components: Set
>    Affects Versions: 3.2
>            Reporter: Michael Qiu
>
> Hey Guys
> I had an interesting problem recently where I was comparing 2 sets and the equals method was returning false... maybe it might be easier to understand if I explain using pseudo code:
> {code}
> set1.equals(set2) = false
> set1.get(0).equals(set2.get(0)) = true
> set1.get(1).equals(set2.get(1)) = true
> set1.get(0).hashCode() == set2.get(0).hashCode() = true
> set1.get(1).hashCode() == set2.get(1).hashCode() = true
> {code}
> So, objects in the two sets are equals, the hashCode of the objects in the two sets are equals, however the equals comparison at the set level was not equals.  
> After some time, we figured out that the problem was that the object inside the set was getting modified after it was put into the set.  So the new hashCode of the object has changed.  However the bucket of the set that it's in hasn't changed.  When another piece of code calls the contains method, it looks for the equivalent object in a bucket according to the new hashCode.  When it doesn't find it, and it returns false.  
> I would like to suggest that the SetUtils.isEqualSet method rehashes contents of the sets given in the parameters before it does the containsAll comparison to avoid the problem caused by this scenario.  

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (COLLECTIONS-311) isEqualSet method in SetUtils could rehash the two input sets before it does the containsAll comparison

Posted by "Stephen Colebourne (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/COLLECTIONS-311?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12663197#action_12663197 ] 

Stephen Colebourne commented on COLLECTIONS-311:
------------------------------------------------

Javadoc from the JDK

"Note: Great care must be exercised if mutable objects are used as set elements. The behavior of a set is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is an element in the set. A special case of this prohibition is that it is not permissible for a set to contain itself as an element. "

http://java.sun.com/j2se/1.5.0/docs/api/java/util/Set.html

While I understand that this caused you many difficulties, it is fundamentally an invalid use of a Set (or Map key) to mutate the object after adding it.

> isEqualSet method in SetUtils could rehash the two input sets before it does the containsAll comparison
> -------------------------------------------------------------------------------------------------------
>
>                 Key: COLLECTIONS-311
>                 URL: https://issues.apache.org/jira/browse/COLLECTIONS-311
>             Project: Commons Collections
>          Issue Type: Improvement
>          Components: Set
>    Affects Versions: 3.2
>            Reporter: Michael Qiu
>
> Hey Guys
> I had an interesting problem recently where I was comparing 2 sets and the equals method was returning false... maybe it might be easier to understand if I explain using pseudo code:
> {code}
> set1.equals(set2) = false
> set1.get(0).equals(set2.get(0)) = true
> set1.get(1).equals(set2.get(1)) = true
> set1.get(0).hashCode() == set2.get(0).hashCode() = true
> set1.get(1).hashCode() == set2.get(1).hashCode() = true
> {code}
> So, objects in the two sets are equals, the hashCode of the objects in the two sets are equals, however the equals comparison at the set level was not equals.  
> After some time, we figured out that the problem was that the object inside the set was getting modified after it was put into the set.  So the new hashCode of the object has changed.  However the bucket of the set that it's in hasn't changed.  When another piece of code calls the contains method, it looks for the equivalent object in a bucket according to the new hashCode.  When it doesn't find it, and it returns false.  
> I would like to suggest that the SetUtils.isEqualSet method rehashes contents of the sets given in the parameters before it does the containsAll comparison to avoid the problem caused by this scenario.  

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.