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

ggregory 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 bde0d12c5 COLLECTIONS-533 Added ArrayListValuedLinkedHashMap
bde0d12c5 is described below

commit bde0d12c51278f1c214f170fea4f804699d92329
Author: Peter De Maeyer <peter.de.mae...@gmail.com>
AuthorDate: Mon Oct 14 21:22:06 2024 +0200

    COLLECTIONS-533 Added ArrayListValuedLinkedHashMap
---
 .../multimap/ArrayListValuedLinkedHashMap.java     | 155 +++++++++++++++++++++
 .../multimap/ArrayListValuedHashMapTest.java       |  12 +-
 ....java => ArrayListValuedLinkedHashMapTest.java} |  53 +++++--
 ...uedLinkedHashMap.emptyCollection.version4.5.obj | Bin 0 -> 123 bytes
 ...luedLinkedHashMap.fullCollection.version4.5.obj | Bin 0 -> 20893 bytes
 5 files changed, 207 insertions(+), 13 deletions(-)

diff --git 
a/src/main/java/org/apache/commons/collections4/multimap/ArrayListValuedLinkedHashMap.java
 
b/src/main/java/org/apache/commons/collections4/multimap/ArrayListValuedLinkedHashMap.java
new file mode 100644
index 000000000..3c238156f
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/collections4/multimap/ArrayListValuedLinkedHashMap.java
@@ -0,0 +1,155 @@
+/*
+ * 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
+ *
+ *      http://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.multimap;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.commons.collections4.MultiValuedMap;
+
+/**
+ * Implements a {@code ListValuedMap}, using a {@link LinkedHashMap} to 
provide data
+ * storage and {@link ArrayList}s as value collections. This is the standard
+ * implementation of a ListValuedMap.
+ * <p>
+ * <strong>Note that ArrayListValuedLinkedHashMap is not synchronized and is 
not
+ * thread-safe.</strong> If you wish to use this map from multiple threads
+ * concurrently, you must use appropriate synchronization. This class may throw
+ * exceptions when accessed by concurrent threads without synchronization.
+ * </p>
+ *
+ * @param <K> the type of the keys in this map
+ * @param <V> the type of the values in this map
+ * @since 4.5
+ */
+public class ArrayListValuedLinkedHashMap<K, V> extends 
AbstractListValuedMap<K, V>
+    implements Serializable {
+
+    /** Serialization Version */
+    private static final long serialVersionUID = 20241014L;
+
+    /**
+     * The initial map capacity used when none specified in constructor.
+     */
+    private static final int DEFAULT_INITIAL_MAP_CAPACITY = 16;
+
+    /**
+     * The initial list capacity when using none specified in constructor.
+     */
+    private static final int DEFAULT_INITIAL_LIST_CAPACITY = 3;
+
+    /**
+     * The initial list capacity when creating a new value collection.
+     */
+    private final int initialListCapacity;
+
+    /**
+     * Creates an empty ArrayListValuedHashMap with the default initial
+     * map capacity (16) and the default initial list capacity (3).
+     */
+    public ArrayListValuedLinkedHashMap() {
+        this(DEFAULT_INITIAL_MAP_CAPACITY, DEFAULT_INITIAL_LIST_CAPACITY);
+    }
+
+    /**
+     * Creates an empty ArrayListValuedHashMap with the default initial
+     * map capacity (16) and the specified initial list capacity.
+     *
+     * @param initialListCapacity  the initial capacity used for value 
collections
+     */
+    public ArrayListValuedLinkedHashMap(final int initialListCapacity) {
+        this(DEFAULT_INITIAL_MAP_CAPACITY, initialListCapacity);
+    }
+
+    /**
+     * Creates an empty ArrayListValuedHashMap with the specified initial
+     * map and list capacities.
+     *
+     * @param initialMapCapacity  the initial hashmap capacity
+     * @param initialListCapacity  the initial capacity used for value 
collections
+     */
+    public ArrayListValuedLinkedHashMap(final int initialMapCapacity, final 
int initialListCapacity) {
+        super(new LinkedHashMap<>(initialMapCapacity));
+        this.initialListCapacity = initialListCapacity;
+    }
+
+    /**
+     * Creates an ArrayListValuedHashMap copying all the mappings of the given 
map.
+     *
+     * @param map a {@code Map} to copy into this map
+     */
+    public ArrayListValuedLinkedHashMap(final Map<? extends K, ? extends V> 
map) {
+        this(map.size(), DEFAULT_INITIAL_LIST_CAPACITY);
+        super.putAll(map);
+    }
+
+    /**
+     * Creates an ArrayListValuedHashMap copying all the mappings of the given 
map.
+     *
+     * @param map a {@code MultiValuedMap} to copy into this map
+     */
+    public ArrayListValuedLinkedHashMap(final MultiValuedMap<? extends K, ? 
extends V> map) {
+        this(map.size(), DEFAULT_INITIAL_LIST_CAPACITY);
+        super.putAll(map);
+    }
+
+    @Override
+    protected ArrayList<V> createCollection() {
+        return new ArrayList<>(initialListCapacity);
+    }
+
+    /**
+     * Deserializes an instance from an ObjectInputStream.
+     *
+     * @param in The source ObjectInputStream.
+     * @throws IOException            Any of the usual Input/Output related 
exceptions.
+     * @throws ClassNotFoundException A class of a serialized object cannot be 
found.
+     */
+    private void readObject(final ObjectInputStream in) throws IOException, 
ClassNotFoundException {
+        in.defaultReadObject();
+        setMap(new LinkedHashMap<>());
+        doReadObject(in);
+    }
+
+    /**
+     * Trims the capacity of all value collections to their current size.
+     */
+    public void trimToSize() {
+        for (final Collection<V> coll : getMap().values()) {
+            final ArrayList<V> list = (ArrayList<V>) coll;
+            list.trimToSize();
+        }
+    }
+
+    /**
+     * Serializes this object to an ObjectOutputStream.
+     *
+     * @param out the target ObjectOutputStream.
+     * @throws IOException thrown when an I/O errors occur writing to the 
target stream.
+     */
+    private void writeObject(final ObjectOutputStream out) throws IOException {
+        out.defaultWriteObject();
+        doWriteObject(out);
+    }
+
+}
diff --git 
a/src/test/java/org/apache/commons/collections4/multimap/ArrayListValuedHashMapTest.java
 
b/src/test/java/org/apache/commons/collections4/multimap/ArrayListValuedHashMapTest.java
index 89830a9d0..aed4b1414 100644
--- 
a/src/test/java/org/apache/commons/collections4/multimap/ArrayListValuedHashMapTest.java
+++ 
b/src/test/java/org/apache/commons/collections4/multimap/ArrayListValuedHashMapTest.java
@@ -254,11 +254,19 @@ public class ArrayListValuedHashMapTest<K, V> extends 
AbstractMultiValuedMapTest
         assertEquals("Q", list3.get(2));
     }
 
+    @Test
+    public void testCopyConstructorWithMultiValuedMap() {
+        final ListValuedMap<K, V> map = makeObject();
+        map.put((K) "key", (V) "sleutel");
+        final ListValuedMap<K, V> copy = new ArrayListValuedHashMap<>(map);
+        assertEquals(map, copy);
+    }
+
 //    public void testCreate() throws Exception {
 //        writeExternalFormToDisk((java.io.Serializable) makeObject(),
-//                
"src/test/resources/data/test/ArrayListValuedHashMap.emptyCollection.version4.1.obj");
+//                
"src/test/resources/org/apache/commons/collections4/data/test/ArrayListValuedHashMap.emptyCollection.version4.1.obj");
 //        writeExternalFormToDisk((java.io.Serializable) makeFullMap(),
-//                
"src/test/resources/data/test/ArrayListValuedHashMap.fullCollection.version4.1.obj");
+//                
"src/test/resources/org/apache/commons/collections4/data/test/ArrayListValuedHashMap.fullCollection.version4.1.obj");
 //    }
 
 }
diff --git 
a/src/test/java/org/apache/commons/collections4/multimap/ArrayListValuedHashMapTest.java
 
b/src/test/java/org/apache/commons/collections4/multimap/ArrayListValuedLinkedHashMapTest.java
similarity index 81%
copy from 
src/test/java/org/apache/commons/collections4/multimap/ArrayListValuedHashMapTest.java
copy to 
src/test/java/org/apache/commons/collections4/multimap/ArrayListValuedLinkedHashMapTest.java
index 89830a9d0..a05758f63 100644
--- 
a/src/test/java/org/apache/commons/collections4/multimap/ArrayListValuedHashMapTest.java
+++ 
b/src/test/java/org/apache/commons/collections4/multimap/ArrayListValuedLinkedHashMapTest.java
@@ -29,17 +29,18 @@ import java.util.ListIterator;
 import java.util.Map;
 
 import org.apache.commons.collections4.ListValuedMap;
+import org.apache.commons.collections4.MapIterator;
 import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.collections4.collection.AbstractCollectionTest;
 import org.junit.jupiter.api.Test;
 
 /**
- * Tests {@link ArrayListValuedHashMap}.
+ * Tests {@link ArrayListValuedLinkedHashMap}.
  */
-public class ArrayListValuedHashMapTest<K, V> extends 
AbstractMultiValuedMapTest<K, V> {
+public class ArrayListValuedLinkedHashMapTest<K, V> extends 
AbstractMultiValuedMapTest<K, V> {
 
-    public ArrayListValuedHashMapTest() {
-        super(ArrayListValuedHashMapTest.class.getSimpleName());
+    public ArrayListValuedLinkedHashMapTest() {
+        super(ArrayListValuedLinkedHashMapTest.class.getSimpleName());
     }
 
     @Override
@@ -49,11 +50,16 @@ public class ArrayListValuedHashMapTest<K, V> extends 
AbstractMultiValuedMapTest
 
     @Override
     public ListValuedMap<K, V> makeObject() {
-        return new ArrayListValuedHashMap<>();
+        return new ArrayListValuedLinkedHashMap<>();
+    }
+
+    @Override
+    public String getCompatibilityVersion() {
+        return "4.5"; // ArrayListValuedLinkedHashMap has been added in 
version 4.5
     }
 
     @Test
-    public void testArrayListValuedHashMap() {
+    public void testArrayListValuedLinkedHashMap() {
         final ListValuedMap<K, V> listMap;
         final ListValuedMap<K, V> listMap1;
         final Map<K, V> map = new HashMap<>();
@@ -62,12 +68,12 @@ public class ArrayListValuedHashMapTest<K, V> extends 
AbstractMultiValuedMapTest
         map.put((K) "B", (V) "X");
         map.put((K) "C", (V) "F");
 
-        listMap = new ArrayListValuedHashMap<>(map);
+        listMap = new ArrayListValuedLinkedHashMap<>(map);
         assertEquals(1, listMap.get((K) "A").size());
         assertEquals(1, listMap.get((K) "B").size());
         assertEquals(1, listMap.get((K) "C").size());
 
-        listMap1 = new ArrayListValuedHashMap<>(map1);
+        listMap1 = new ArrayListValuedLinkedHashMap<>(map1);
         assertEquals("{}", listMap1.toString());
     }
 
@@ -177,7 +183,7 @@ public class ArrayListValuedHashMapTest<K, V> extends 
AbstractMultiValuedMapTest
 
     @Test
     public void testTrimToSize() {
-        final ArrayListValuedHashMap<K, V> listMap = new 
ArrayListValuedHashMap<>(4);
+        final ArrayListValuedLinkedHashMap<K, V> listMap = new 
ArrayListValuedLinkedHashMap<>(4);
 
         assertEquals("{}", listMap.toString());
         listMap.put((K) "A", (V) "W");
@@ -254,11 +260,36 @@ public class ArrayListValuedHashMapTest<K, V> extends 
AbstractMultiValuedMapTest
         assertEquals("Q", list3.get(2));
     }
 
+    @Test
+    public void testPreservesKeyInsertionOrder() {
+        final ListValuedMap<K, V> map = makeObject();
+        map.put((K) Integer.valueOf(5), (V) "five");
+        map.put((K) Integer.valueOf(1), (V) "one");
+        map.put((K) Integer.valueOf(5), (V) "vijf"); // "vijf" = "five" in 
Dutch
+        MapIterator<K, V> mapIterator = map.mapIterator();
+        assertEquals(5, mapIterator.next());
+        assertEquals("five", mapIterator.getValue());
+        assertEquals(5, mapIterator.next());
+        assertEquals("vijf", mapIterator.getValue());
+        assertEquals(1, mapIterator.next());
+        assertEquals("one", mapIterator.getValue());
+        assertFalse(mapIterator.hasNext());
+    }
+
+    @Test
+    public void testCopyConstructorWithMultiValuedMap() {
+        final ListValuedMap<K, V> map = makeObject();
+        map.put((K) "key", (V) "sleutel");
+        final ListValuedMap<K, V> copy = new 
ArrayListValuedLinkedHashMap<>(map);
+        assertEquals(map, copy);
+    }
+
+//    @Test
 //    public void testCreate() throws Exception {
 //        writeExternalFormToDisk((java.io.Serializable) makeObject(),
-//                
"src/test/resources/data/test/ArrayListValuedHashMap.emptyCollection.version4.1.obj");
+//                
"src/test/resources/org/apache/commons/collections4/data/test/ArrayListValuedLinkedHashMap.emptyCollection.version4.5.obj");
 //        writeExternalFormToDisk((java.io.Serializable) makeFullMap(),
-//                
"src/test/resources/data/test/ArrayListValuedHashMap.fullCollection.version4.1.obj");
+//                
"src/test/resources/org/apache/commons/collections4/data/test/ArrayListValuedLinkedHashMap.fullCollection.version4.5.obj");
 //    }
 
 }
diff --git 
a/src/test/resources/org/apache/commons/collections4/data/test/ArrayListValuedLinkedHashMap.emptyCollection.version4.5.obj
 
b/src/test/resources/org/apache/commons/collections4/data/test/ArrayListValuedLinkedHashMap.emptyCollection.version4.5.obj
new file mode 100644
index 000000000..1b2bd01f8
Binary files /dev/null and 
b/src/test/resources/org/apache/commons/collections4/data/test/ArrayListValuedLinkedHashMap.emptyCollection.version4.5.obj
 differ
diff --git 
a/src/test/resources/org/apache/commons/collections4/data/test/ArrayListValuedLinkedHashMap.fullCollection.version4.5.obj
 
b/src/test/resources/org/apache/commons/collections4/data/test/ArrayListValuedLinkedHashMap.fullCollection.version4.5.obj
new file mode 100644
index 000000000..7499484e0
Binary files /dev/null and 
b/src/test/resources/org/apache/commons/collections4/data/test/ArrayListValuedLinkedHashMap.fullCollection.version4.5.obj
 differ

Reply via email to