[COLLECTIONS-533] Revert incomplete implementation.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/collections/trunk@1683011 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Thomas Neidhart 2015-06-01 21:59:10 +00:00
parent d4fbeefc52
commit 1c0b6089f4
2 changed files with 0 additions and 533 deletions

View File

@ -1,265 +0,0 @@
/*
* 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.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.collections4.ListValuedMap;
import org.apache.commons.collections4.MultiValuedMap;
import org.apache.commons.collections4.SetValuedMap;
/**
* Implements a {@link MultiValuedMap}, using a {@link LinkedHashMap} to provide
* data storage. This MultiValuedMap implementation the allows insertion order
* to be maintained.
* <p>
* A <code>MultiValuedMap</code> is a Map with slightly different semantics.
* Putting a value into the map will add the value to a Collection at that key.
* Getting a value will return a Collection, holding all the values put to that
* key
* <p>
* In addition, this implementation allows the type of collection used for the
* values to be controlled. By default, an <code>LinkedList</code> is used,
* however a <code>Class<? extends Collection></code> to instantiate the value
* collection may be specified.
* <p>
* <strong>Note that MultiValuedLinkedHashMap 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.
*
* @since 4.1
* @version $Id$
*/
public class MultiValuedLinkedHashMap<K, V> extends AbstractMultiValuedMap<K, V> {
/** Serialization Version */
private static final long serialVersionUID = -5845183518195365857L;
/**
* The initial capacity used when none specified in constructor.
*/
static final int DEFAULT_INITIAL_CAPACITY = 16;
/**
* The load factor used when none specified in constructor.
*/
static final float DEFAULT_LOAD_FACTOR = 0.75f;
/**
* Creates a {@link ListValuedMap} with a {@link LinkedHashMap} as its internal
* storage
*
* @param <K> the key type
* @param <V> the value type
* @return a new <code>ListValuedMap</code>
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static <K, V> ListValuedMap<K, V> listValuedLinkedHashMap() {
return new ListValuedLinkedHashMap(LinkedList.class);
}
/**
* Creates a {@link ListValuedMap} with a {@link LinkedHashMap} as its internal
* storage which maps the keys to list of type <code>listClass</code>
*
* @param <K> the key type
* @param <V> the value type
* @param <C> the List class type
* @param listClass the class of the list
* @return a new <code>ListValuedMap</code>
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static <K, V, C extends List<V>> ListValuedMap<K, V> listValuedLinkedHashMap(final Class<C> listClass) {
return new ListValuedLinkedHashMap(listClass);
}
/**
* Creates a {@link SetValuedMap} with a {@link LinkedHashMap} as its internal
* storage. This <code>SetValuedMap</code> implementation uses {@link LinkedHashSet} as its
* underlying <code>Collection</code> to preserve the item insertion order
*
* @param <K> the key type
* @param <V> the value type
* @return a new <code>SetValuedMap</code>
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static <K, V> SetValuedMap<K, V> setValuedLinkedHashMap() {
return new SetValuedLinkedHashMap(LinkedHashSet.class);
}
/**
* Creates a {@link SetValuedMap} with a {@link LinkedHashMap} as its internal
* storage which maps the keys to a set of type <code>setClass</code>
*
* @param <K> the key type
* @param <V> the value type
* @param <C> the Set class type
* @param setClass the class of the set
* @return a new <code>SetValuedMap</code>
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static <K, V, C extends Set<V>> SetValuedMap<K, V> setValuedLinkedHashMap(final Class<C> setClass) {
return new SetValuedLinkedHashMap(setClass);
}
/**
* Creates a MultiValueMap based on a <code>LinkedHashMap</code> with the default
* initial capacity (16) and the default load factor (0.75), which stores
* the multiple values in an <code>LinkedList</code>.
*/
@SuppressWarnings("unchecked")
public MultiValuedLinkedHashMap() {
this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, LinkedList.class);
}
/**
* Creates a MultiValueMap based on a <code>LinkedHashMap</code> with the initial
* capacity and the default load factor (0.75), which stores the multiple
* values in an <code>LinkedList</code>.
*
* @param initialCapacity the initial capacity of the underlying hash map
*/
@SuppressWarnings("unchecked")
public MultiValuedLinkedHashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR, LinkedList.class);
}
/**
* Creates a MultiValueMap based on a <code>LinkedHashMap</code> with the initial
* capacity and the load factor, which stores the multiple values in an
* <code>LinkedList</code>.
*
* @param initialCapacity the initial capacity of the underlying hash map
* @param loadFactor the load factor of the underlying hash map
*/
@SuppressWarnings("unchecked")
public MultiValuedLinkedHashMap(int initialCapacity, float loadFactor) {
this(initialCapacity, loadFactor, LinkedList.class);
}
/**
* Creates a MultiValueMap based on a <code>LinkedHashMap</code> with the initial
* capacity and the load factor, which stores the multiple values in an
* <code>LinkedList</code> with the initial collection capacity.
*
* @param initialCapacity the initial capacity of the underlying hash map
* @param loadFactor the load factor of the underlying hash map
* @param initialCollectionCapacity the initial capacity of the Collection
* of values
*/
@SuppressWarnings("unchecked")
public MultiValuedLinkedHashMap(int initialCapacity, float loadFactor, int initialCollectionCapacity) {
this(initialCapacity, loadFactor, LinkedList.class, initialCollectionCapacity);
}
/**
* Creates a MultiValuedLinkedHashMap copying all the mappings of the given map.
*
* @param map a <code>MultiValuedMap</code> to copy into this map
*/
@SuppressWarnings("unchecked")
public MultiValuedLinkedHashMap(final MultiValuedMap<? extends K, ? extends V> map) {
this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, LinkedList.class);
super.putAll(map);
}
/**
* Creates a MultiValuedLinkedHashMap copying all the mappings of the given map.
*
* @param map a <code>Map</code> to copy into this map
*/
@SuppressWarnings("unchecked")
public MultiValuedLinkedHashMap(final Map<? extends K, ? extends V> map) {
this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, LinkedList.class);
super.putAll(map);
}
/**
* Creates a MultiValuedLinkedHashMap which creates the value collections using
* the supplied <code>collectionClazz</code>.
*
* @param initialCapacity the initial capacity of the underlying
* <code>LinkedHashMap</code>
* @param loadFactor the load factor of the underlying <code>LinkedHashMap</code>
* @param <C> the collection type
* @param collectionClazz the class of the <code>Collection</code> to use to
* create the value collections
*/
protected <C extends Collection<V>> MultiValuedLinkedHashMap(int initialCapacity, float loadFactor,
final Class<C> collectionClazz) {
super(new LinkedHashMap<K, Collection<V>>(initialCapacity, loadFactor), collectionClazz);
}
/**
* Creates a MultiValuedLinkedHashMap which creates the value collections using
* the supplied <code>collectionClazz</code> and the initial collection
* capacity .
*
* @param initialCapacity the initial capacity of the underlying
* <code>LinkedHashMap</code>
* @param loadFactor the load factor of the underlying <code>LinkedHashMap</code>
* @param initialCollectionCapacity the initial capacity of the
* <code>Collection</code>
* @param <C> the collection type
* @param collectionClazz the class of the <code>Collection</code> to use to
* create the value collections
*/
protected <C extends Collection<V>> MultiValuedLinkedHashMap(int initialCapacity, float loadFactor,
final Class<C> collectionClazz, int initialCollectionCapacity) {
super(new LinkedHashMap<K, Collection<V>>(initialCapacity, loadFactor), collectionClazz,
initialCollectionCapacity);
}
/** Inner class for ListValuedLinkedMap */
private static class ListValuedLinkedHashMap<K, V> extends AbstractListValuedMap<K, V> {
private static final long serialVersionUID = 3667581458573135234L;
public <C extends List<V>> ListValuedLinkedHashMap(Class<C> listClazz) {
super(new LinkedHashMap<K, List<V>>(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR), listClazz);
}
public <C extends List<V>> ListValuedLinkedHashMap(Class<C> listClazz, int initialListCapacity) {
super(new LinkedHashMap<K, List<V>>(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR), listClazz,
initialListCapacity);
}
}
/** Inner class for SetValuedLinkedMap */
private static class SetValuedLinkedHashMap<K, V> extends AbstractSetValuedMap<K, V> {
private static final long serialVersionUID = -3817515514829894543L;
public <C extends Set<V>> SetValuedLinkedHashMap(Class<C> setClazz) {
super(new LinkedHashMap<K, Set<V>>(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR), setClazz);
}
public <C extends Set<V>> SetValuedLinkedHashMap(Class<C> setClazz, int initialSetCapacity) {
super(new LinkedHashMap<K, Set<V>>(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR), setClazz,
initialSetCapacity);
}
}
}

View File

@ -1,268 +0,0 @@
/*
* 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.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
import junit.framework.Test;
import org.apache.commons.collections4.BulkTest;
import org.apache.commons.collections4.ListValuedMap;
import org.apache.commons.collections4.MapIterator;
import org.apache.commons.collections4.MultiValuedMap;
import org.apache.commons.collections4.SetValuedMap;
/**
* Test MultiValuedLinkedHashMap
*
* @since 4.1
* @version $Id$
*/
public class MultiValuedLinkedHashMapTest<K, V> extends AbstractMultiValuedMapTest<K, V> {
public MultiValuedLinkedHashMapTest(String testName) {
super(testName);
}
public static Test suite() {
return BulkTest.makeSuite(MultiValuedLinkedHashMapTest.class);
}
@Override
public MultiValuedMap<K, V> makeObject() {
final MultiValuedMap<K, V> m = new MultiValuedLinkedHashMap<K, V>();
return m;
}
public void testIterationOrder() {
MultiValuedMap<K, V> map = makeFullMap();
MapIterator<K, V> mapIt = map.mapIterator();
Iterator<K> keyIt = Arrays.asList(getSampleKeys()).iterator();
Iterator<V> valueIt = Arrays.asList(getSampleValues()).iterator();
while(mapIt.hasNext()) {
mapIt.next();
assertEquals(mapIt.getKey(), keyIt.next());
assertEquals(mapIt.getValue(), valueIt.next());
}
}
@SuppressWarnings("unchecked")
public void testSetValuedMapAdd() {
final SetValuedMap<K, V> setMap = MultiValuedLinkedHashMap.setValuedLinkedHashMap();
assertTrue(setMap.get("whatever") instanceof Set);
Set<V> set = setMap.get("A");
assertTrue(set.add((V) "a1"));
assertTrue(set.add((V) "a2"));
assertFalse(set.add((V) "a1"));
assertEquals(2, setMap.size());
assertTrue(setMap.containsKey("A"));
}
@SuppressWarnings("unchecked")
public void testSetValuedMapRemove() {
final SetValuedMap<K, V> setMap = MultiValuedLinkedHashMap.setValuedLinkedHashMap();
assertTrue(setMap.get("whatever") instanceof Set);
Set<V> set = setMap.get("A");
assertTrue(set.add((V) "a1"));
assertTrue(set.add((V) "a2"));
assertFalse(set.add((V) "a1"));
assertEquals(2, setMap.size());
assertTrue(setMap.containsKey("A"));
assertTrue(set.remove("a1"));
assertTrue(set.remove("a2"));
assertFalse(set.remove("a1"));
assertEquals(0, setMap.size());
assertFalse(setMap.containsKey("A"));
}
@SuppressWarnings("unchecked")
public void testSetValuedMapRemoveViaIterator() {
final SetValuedMap<K, V> setMap = MultiValuedLinkedHashMap.setValuedLinkedHashMap();
assertTrue(setMap.get("whatever") instanceof Set);
Set<V> set = setMap.get("A");
set.add((V) "a1");
set.add((V) "a2");
set.add((V) "a1");
Iterator<V> it = set.iterator();
while (it.hasNext()) {
it.next();
it.remove();
}
assertEquals(0, setMap.size());
assertFalse(setMap.containsKey("A"));
}
public void testSetValuedMapIterationOrder() {
SetValuedMap<K, V> setMap = MultiValuedLinkedHashMap.setValuedLinkedHashMap();
addSampleMappings(setMap);
MapIterator<K, V> mapIt = setMap.mapIterator();
Iterator<K> keyIt = Arrays.asList(getSampleKeys()).iterator();
Iterator<V> valueIt = Arrays.asList(getSampleValues()).iterator();
while(mapIt.hasNext()) {
mapIt.next();
assertEquals(mapIt.getKey(), keyIt.next());
assertEquals(mapIt.getValue(), valueIt.next());
}
}
@SuppressWarnings("unchecked")
public void testListValuedMapAdd() {
final ListValuedMap<K, V> listMap = MultiValuedLinkedHashMap.listValuedLinkedHashMap();
assertTrue(listMap.get("whatever") instanceof List);
List<V> list = listMap.get("A");
list.add((V) "a1");
assertEquals(1, listMap.size());
assertTrue(listMap.containsKey("A"));
}
@SuppressWarnings("unchecked")
public void testListValuedMapAddViaListIterator() {
final ListValuedMap<K, V> listMap = MultiValuedLinkedHashMap.listValuedLinkedHashMap();
ListIterator<V> listIt = listMap.get("B").listIterator();
assertFalse(listIt.hasNext());
listIt.add((V) "b1");
listIt.add((V) "b2");
listIt.add((V) "b3");
assertEquals(3, listMap.size());
assertTrue(listMap.containsKey("B"));
// As ListIterator always adds before the current cursor
assertFalse(listIt.hasNext());
}
@SuppressWarnings("unchecked")
public void testListValuedMapRemove() {
final ListValuedMap<K, V> listMap = MultiValuedLinkedHashMap.listValuedLinkedHashMap();
List<V> list = listMap.get("A");
list.add((V) "a1");
list.add((V) "a2");
list.add((V) "a3");
assertEquals(3, listMap.size());
assertEquals("a1", list.remove(0));
assertEquals(2, listMap.size());
assertEquals("a2", list.remove(0));
assertEquals(1, listMap.size());
assertEquals("a3", list.remove(0));
assertEquals(0, listMap.size());
assertFalse(listMap.containsKey("A"));
}
@SuppressWarnings("unchecked")
public void testListValuedMapRemoveViaListIterator() {
final ListValuedMap<K, V> listMap = MultiValuedLinkedHashMap.listValuedLinkedHashMap();
ListIterator<V> listIt = listMap.get("B").listIterator();
listIt.add((V) "b1");
listIt.add((V) "b2");
assertEquals(2, listMap.size());
assertTrue(listMap.containsKey("B"));
listIt = listMap.get("B").listIterator();
while (listIt.hasNext()) {
listIt.next();
listIt.remove();
}
assertFalse(listMap.containsKey("B"));
listIt.add((V) "b1");
listIt.add((V) "b2");
assertTrue(listMap.containsKey("B"));
assertEquals(2, listMap.get("B").size());
}
public void testListValuedMapIterationOrder() {
ListValuedMap<K, V> listMap = MultiValuedLinkedHashMap.listValuedLinkedHashMap();
addSampleMappings(listMap);
MapIterator<K, V> mapIt = listMap.mapIterator();
Iterator<K> keyIt = Arrays.asList(getSampleKeys()).iterator();
Iterator<V> valueIt = Arrays.asList(getSampleValues()).iterator();
while(mapIt.hasNext()) {
mapIt.next();
assertEquals(mapIt.getKey(), keyIt.next());
assertEquals(mapIt.getValue(), valueIt.next());
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public void testEqualsHashCodeContract() {
MultiValuedMap map1 = new MultiValuedLinkedHashMap();
MultiValuedMap map2 = new MultiValuedLinkedHashMap();
map1.put("a", "a1");
map1.put("a", "a2");
map2.put("a", "a2");
map2.put("a", "a1");
assertEquals(map1, map2);
assertEquals(map1.hashCode(), map2.hashCode());
map2.put("a", "a2");
assertNotSame(map1, map2);
assertNotSame(map1.hashCode(), map2.hashCode());
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public void testListValuedMapEqualsHashCodeContract() {
ListValuedMap map1 = MultiValuedLinkedHashMap.listValuedLinkedHashMap();
ListValuedMap map2 = MultiValuedLinkedHashMap.listValuedLinkedHashMap();
map1.put("a", "a1");
map1.put("a", "a2");
map2.put("a", "a1");
map2.put("a", "a2");
assertEquals(map1, map2);
assertEquals(map1.hashCode(), map2.hashCode());
map1.put("b", "b1");
map1.put("b", "b2");
map2.put("b", "b2");
map2.put("b", "b1");
assertNotSame(map1, map2);
assertNotSame(map1.hashCode(), map2.hashCode());
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public void testSetValuedMapEqualsHashCodeContract() {
SetValuedMap map1 = MultiValuedLinkedHashMap.setValuedLinkedHashMap();
SetValuedMap map2 = MultiValuedLinkedHashMap.setValuedLinkedHashMap();
map1.put("a", "a1");
map1.put("a", "a2");
map2.put("a", "a2");
map2.put("a", "a1");
assertEquals(map1, map2);
assertEquals(map1.hashCode(), map2.hashCode());
map2.put("a", "a2");
assertEquals(map1, map2);
assertEquals(map1.hashCode(), map2.hashCode());
map2.put("a", "a3");
assertNotSame(map1, map2);
assertNotSame(map1.hashCode(), map2.hashCode());
}
}