Ruiqi Dong created COLLECTIONS-891:
--------------------------------------

             Summary: IndexedCollection.contains() can return true for objects 
that were never added
                 Key: COLLECTIONS-891
                 URL: https://issues.apache.org/jira/browse/COLLECTIONS-891
             Project: Commons Collections
          Issue Type: Bug
          Components: Collection
            Reporter: Ruiqi Dong


*Summary*
`IndexedCollection` is still a `Collection`, so `contains(x)` should answer 
whether an equal object is present in the collection.
 
The current implementation answers a different question: whether the collection 
contains *any* element whose transformed key matches `keyTransformer.apply(x)`.

That produces false positives whenever two different objects map to the same 
key.
 
*Affected code*
File: 
`src/main/java/org/apache/commons/collections4/collection/IndexedCollection.java`
{code:java}
@SuppressWarnings("unchecked")
@Override
public boolean contains(final Object object) {
    return index.containsKey(keyTransformer.apply((C) object));
} {code}
*Reproducer*
Add the following test to 
`src/test/java/org/apache/commons/collections4/collection/IndexedCollectionTest.java`:
{code:java}
@Test
void testContainsUsesObjectEqualityNotOnlyTransformedKey() {
    final Collection<String> coll = makeUniqueTestCollection();
    coll.add("01");

    assertFalse(coll.contains("1"));
} {code}
This uses the existing `IntegerTransformer`, so both `"01"` and `"1"` map to 
the same key `1`, but the objects are not equal.
 
Run:
{code:java}
mvn -q 
-Dtest=org.apache.commons.collections4.collection.IndexedCollectionTest#testContainsUsesObjectEqualityNotOnlyTransformedKey
 test {code}
*Observed behavior*
{code:java}
expected: <false> but was: <true> {code}
*Expected behavior*
`contains("1")` should be `false`, because only `"01"` was added to the 
collection.
 
The class is a `Collection` decorator, not just a key index. Its `contains` 
method must preserve collection membership semantics. Matching on transformed 
keys instead of object equality breaks the `Collection.contains` contract 
whenever the transformer is not injective.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to