Ruiqi Dong created COLLECTIONS-889:
--------------------------------------

             Summary: `IndexedCollection.remove()` clears the whole key bucket 
in non-unique indexes
                 Key: COLLECTIONS-889
                 URL: https://issues.apache.org/jira/browse/COLLECTIONS-889
             Project: Commons Collections
          Issue Type: Bug
          Components: Collection
            Reporter: Ruiqi Dong


*Summary*
For non-unique indexes, multiple collection elements may share the same 
transformed key. The current `remove(...)` implementation removes the object 
from the decorated collection correctly, but then removes the entire key from 
the index. That drops the remaining same-key elements from the index even 
though they are still present in the collection.
 
*Affected code*
File: 
`src/main/java/org/apache/commons/collections4/collection/IndexedCollection.java`
{code:java}
@SuppressWarnings("unchecked")
@Override
public boolean remove(final Object object) {
    final boolean removed = super.remove(object);
    if (removed) {
        removeFromIndex((C) object);
    }
    return removed;
}

private void removeFromIndex(final C object) {
    index.remove(keyTransformer.apply(object));
} {code}
*Reproducer* 
Add the following test to 
`src/test/java/org/apache/commons/collections4/collection/IndexedCollectionTest.java`
{code:java}
@Test
void testRemovePreservesRemainingValuesWithSameTransformedKey() {
    final IndexedCollection<Integer, String> indexed =
            (IndexedCollection<Integer, String>) decorateCollection(new 
ArrayList<>());
    indexed.add("01");
    indexed.add("1");

    indexed.remove("01");

    assertEquals("1", indexed.get(1));
    assertNotNull(indexed.values(1));
    assertEquals(asList("1"), new ArrayList<>(indexed.values(1)));
} {code}
Run:
{code:java}
mvn -q 
-Dtest=org.apache.commons.collections4.collection.IndexedCollectionTest#testRemovePreservesRemainingValuesWithSameTransformedKey
 test {code}
Observed behavior:
`get(1)` returns `null` even though `"1"` is still present in the decorated 
collection.
{code:java}
expected: <1> but was: <null> {code}
Expected behavior:
Removing `"01"` should leave the other same-key value `"1"` indexed and 
retrievable.

 

In the non-unique configuration, the index is supposed to track all values that 
share a key. Removing one value should only remove that single value from the 
index entry, not delete the whole key bucket. The current implementation leaves 
the collection and the index out of sync after a normal successful 
`remove(...)`.



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

Reply via email to