This is an automated email from the ASF dual-hosted git repository.

garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-collections.git


The following commit(s) were added to refs/heads/master by this push:
     new 95283b08e Do not mutate the input map in 
SwitchTransformer.switchTransformer (#696)
95283b08e is described below

commit 95283b08ea1ec83b09b4bb8ae0c8004da5476b8d
Author: Vasiliy Mikhailov <[email protected]>
AuthorDate: Sun Jun 28 16:19:47 2026 +0400

    Do not mutate the input map in SwitchTransformer.switchTransformer (#696)
    
    * Do not mutate the input map in SwitchTransformer.switchTransformer
    
    switchTransformer(Map) extracted the default with map.remove(null), which
    removes the null key from the caller list map as a side effect. Use
    map.get(null) so the factory method leaves the input map unchanged.
    
    * Declutter new test.
    
    * Fix mess in test.
    
    ---------
    
    Co-authored-by: Gary Gregory <[email protected]>
---
 .../collections4/functors/SwitchTransformer.java   | 12 ++---
 .../functors/SwitchTransformerMapMutatesTest.java  | 52 ++++++++++++++++++++++
 2 files changed, 59 insertions(+), 5 deletions(-)

diff --git 
a/src/main/java/org/apache/commons/collections4/functors/SwitchTransformer.java 
b/src/main/java/org/apache/commons/collections4/functors/SwitchTransformer.java
index 213d1d5b9..a1dd1b623 100644
--- 
a/src/main/java/org/apache/commons/collections4/functors/SwitchTransformer.java
+++ 
b/src/main/java/org/apache/commons/collections4/functors/SwitchTransformer.java
@@ -17,6 +17,7 @@
 package org.apache.commons.collections4.functors;
 
 import java.io.Serializable;
+import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Objects;
 
@@ -63,9 +64,10 @@ public class SwitchTransformer<T, R> implements 
Transformer<T, R>, Serializable
         if (map.isEmpty()) {
             return ConstantTransformer.<I, O>nullTransformer();
         }
-        // convert to array like this to guarantee iterator() ordering
-        final Transformer<? super I, ? extends O> defaultTransformer = 
map.remove(null);
-        final int size = map.size();
+        // copy so the caller's map is not mutated; LinkedHashMap preserves 
iterator() ordering
+        final Map<Predicate<? super I>, Transformer<? super I, ? extends O>> 
entries = new LinkedHashMap<>(map);
+        final Transformer<? super I, ? extends O> defaultTransformer = 
entries.remove(null);
+        final int size = entries.size();
         if (size == 0) {
             return (Transformer<I, O>) (defaultTransformer == null ? 
ConstantTransformer.<I, O>nullTransformer() :
                                                                      
defaultTransformer);
@@ -73,8 +75,8 @@ public class SwitchTransformer<T, R> implements 
Transformer<T, R>, Serializable
         final Transformer<? super I, ? extends O>[] transformers = new 
Transformer[size];
         final Predicate<? super I>[] preds = new Predicate[size];
         int i = 0;
-        for (final Map.Entry<? extends Predicate<? super I>,
-                             ? extends Transformer<? super I, ? extends O>> 
entry : map.entrySet()) {
+        for (final Map.Entry<Predicate<? super I>,
+                             Transformer<? super I, ? extends O>> entry : 
entries.entrySet()) {
             preds[i] = entry.getKey();
             transformers[i] = entry.getValue();
             i++;
diff --git 
a/src/test/java/org/apache/commons/collections4/functors/SwitchTransformerMapMutatesTest.java
 
b/src/test/java/org/apache/commons/collections4/functors/SwitchTransformerMapMutatesTest.java
new file mode 100644
index 000000000..3cde12068
--- /dev/null
+++ 
b/src/test/java/org/apache/commons/collections4/functors/SwitchTransformerMapMutatesTest.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.functors;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.collections4.Transformer;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests that SwitchTransformer.switchTransformer(Map) does not mutate the 
input map.
+ */
+class SwitchTransformerMapMutatesTest {
+
+    /**
+     * Tests that switchTransformer(Map) does NOT mutate the input map by 
removing the null key.
+     */
+    @Test
+    void testSwitchTransformerMapDoesNotMutateInput() {
+        final Transformer<String, String> defaultTransformer = 
ConstantTransformer.constantTransformer("default");
+        final Transformer<String, String> transformer = 
ConstantTransformer.constantTransformer("value");
+        final Predicate<String> predicate = NullPredicate.nullPredicate();
+        final Map<Predicate<String>, Transformer<String, String>> map = new 
LinkedHashMap<>();
+        map.put(null, defaultTransformer);
+        map.put(predicate, transformer);
+        final int sizeBefore = map.size();
+        assertEquals(2, sizeBefore);
+        // Call the factory method
+        SwitchTransformer.switchTransformer(map);
+        // The map should NOT have been mutated - null key must still be 
present
+        final int sizeAfter = map.size();
+        assertEquals(sizeBefore, sizeAfter, "switchTransformer must not mutate 
the input map; expected size");
+    }
+}

Reply via email to