/*
 * 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;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.collections4.bag.HashBag;
import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
import org.apache.commons.collections4.multimap.HashSetValuedHashMap;
import org.apache.commons.collections4.multimap.TransformedMultiValuedMap;
import org.apache.commons.collections4.multimap.UnmodifiableMultiValuedMap;

Provides utility methods and decorators for MultiValuedMap instances.

It contains various type safe and null safe methods. Additionally, it provides the following decorators:

Since:4.1
/** * Provides utility methods and decorators for {@link MultiValuedMap} instances. * <p> * It contains various type safe and null safe methods. Additionally, it provides * the following decorators: * </p> * <ul> * <li>{@link #unmodifiableMultiValuedMap(MultiValuedMap)}</li> * <li>{@link #transformedMultiValuedMap(MultiValuedMap, Transformer, Transformer)}</li> * </ul> * * @since 4.1 */
public class MultiMapUtils {
MultiMapUtils should not normally be instantiated.
/** * <code>MultiMapUtils</code> should not normally be instantiated. */
private MultiMapUtils() {} /** * An empty {@link UnmodifiableMultiValuedMap}. */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static final MultiValuedMap EMPTY_MULTI_VALUED_MAP = UnmodifiableMultiValuedMap.unmodifiableMultiValuedMap(new ArrayListValuedHashMap(0, 0));
Returns immutable EMPTY_MULTI_VALUED_MAP with generic type safety.
Type parameters:
  • <K> – the type of key in the map
  • <V> – the type of value in the map
Returns:immutable and empty MultiValuedMap
/** * Returns immutable EMPTY_MULTI_VALUED_MAP with generic type safety. * * @param <K> the type of key in the map * @param <V> the type of value in the map * @return immutable and empty <code>MultiValuedMap</code> */
@SuppressWarnings("unchecked") public static <K, V> MultiValuedMap<K, V> emptyMultiValuedMap() { return EMPTY_MULTI_VALUED_MAP; } // Null safe methods
Returns an immutable empty MultiValuedMap if the argument is null, or the argument itself otherwise.
Params:
  • map – the map, may be null
Type parameters:
  • <K> – the type of key in the map
  • <V> – the type of value in the map
Returns:an empty MultiValuedMap if the argument is null
/** * Returns an immutable empty <code>MultiValuedMap</code> if the argument is * <code>null</code>, or the argument itself otherwise. * * @param <K> the type of key in the map * @param <V> the type of value in the map * @param map the map, may be null * @return an empty {@link MultiValuedMap} if the argument is null */
@SuppressWarnings("unchecked") public static <K, V> MultiValuedMap<K, V> emptyIfNull(final MultiValuedMap<K, V> map) { return map == null ? EMPTY_MULTI_VALUED_MAP : map; }
Null-safe check if the specified MultiValuedMap is empty.

If the provided map is null, returns true.

Params:
  • map – the map to check, may be null
Returns:true if the map is empty or null
/** * Null-safe check if the specified <code>MultiValuedMap</code> is empty. * <p> * If the provided map is null, returns true. * * @param map the map to check, may be null * @return true if the map is empty or null */
public static boolean isEmpty(final MultiValuedMap<?, ?> map) { return map == null || map.isEmpty(); } // Null safe getters // -------------------------------------------------------------------------
Gets a Collection from MultiValuedMap in a null-safe manner.
Params:
Type parameters:
  • <K> – the key type
  • <V> – the value type
Returns:the Collection in the MultiValuedMap, or null if input map is null
/** * Gets a Collection from <code>MultiValuedMap</code> in a null-safe manner. * * @param <K> the key type * @param <V> the value type * @param map the {@link MultiValuedMap} to use * @param key the key to look up * @return the Collection in the {@link MultiValuedMap}, or null if input map is null */
public static <K, V> Collection<V> getCollection(final MultiValuedMap<K, V> map, final K key) { if (map != null) { return map.get(key); } return null; } // TODO: review the getValuesAsXXX methods - depending on the actual MultiValuedMap type, changes // to the returned collection might update the backing map. This should be clarified and/or prevented.
Gets a List from MultiValuedMap in a null-safe manner.
Params:
Type parameters:
  • <K> – the key type
  • <V> – the value type
Returns:the Collection in the MultiValuedMap as List, or null if input map is null
/** * Gets a List from <code>MultiValuedMap</code> in a null-safe manner. * * @param <K> the key type * @param <V> the value type * @param map the {@link MultiValuedMap} to use * @param key the key to look up * @return the Collection in the {@link MultiValuedMap} as List, or null if input map is null */
public static <K, V> List<V> getValuesAsList(final MultiValuedMap<K, V> map, final K key) { if (map != null) { final Collection<V> col = map.get(key); if (col instanceof List) { return (List<V>) col; } return new ArrayList<>(col); } return null; }
Gets a Set from MultiValuedMap in a null-safe manner.
Params:
Type parameters:
  • <K> – the key type
  • <V> – the value type
Returns:the Collection in the MultiValuedMap as Set, or null if input map is null
/** * Gets a Set from <code>MultiValuedMap</code> in a null-safe manner. * * @param <K> the key type * @param <V> the value type * @param map the {@link MultiValuedMap} to use * @param key the key to look up * @return the Collection in the {@link MultiValuedMap} as Set, or null if input map is null */
public static <K, V> Set<V> getValuesAsSet(final MultiValuedMap<K, V> map, final K key) { if (map != null) { final Collection<V> col = map.get(key); if (col instanceof Set) { return (Set<V>) col; } return new HashSet<>(col); } return null; }
Gets a Bag from MultiValuedMap in a null-safe manner.
Params:
Type parameters:
  • <K> – the key type
  • <V> – the value type
Returns:the Collection in the MultiValuedMap as Bag, or null if input map is null
/** * Gets a Bag from <code>MultiValuedMap</code> in a null-safe manner. * * @param <K> the key type * @param <V> the value type * @param map the {@link MultiValuedMap} to use * @param key the key to look up * @return the Collection in the {@link MultiValuedMap} as Bag, or null if input map is null */
public static <K, V> Bag<V> getValuesAsBag(final MultiValuedMap<K, V> map, final K key) { if (map != null) { final Collection<V> col = map.get(key); if (col instanceof Bag) { return (Bag<V>) col; } return new HashBag<>(col); } return null; } // Factory Methods // -----------------------------------------------------------------------
Creates a ListValuedMap with an ArrayList as collection class to store the values mapped to a key.
Type parameters:
  • <K> – the key type
  • <V> – the value type
Returns:a new ListValuedMap
/** * Creates a {@link ListValuedMap} with an {@link java.util.ArrayList ArrayList} as * collection class to store the values mapped to a key. * * @param <K> the key type * @param <V> the value type * @return a new <code>ListValuedMap</code> */
public static <K, V> ListValuedMap<K, V> newListValuedHashMap() { return new ArrayListValuedHashMap<>(); }
Creates a SetValuedMap with an HashSet as collection class to store the values mapped to a key.
Type parameters:
  • <K> – the key type
  • <V> – the value type
Returns:a new SetValuedMap
/** * Creates a {@link SetValuedMap} with an {@link java.util.HashSet HashSet} as * collection class to store the values mapped to a key. * * @param <K> the key type * @param <V> the value type * @return a new {@link SetValuedMap} */
public static <K, V> SetValuedMap<K, V> newSetValuedHashMap() { return new HashSetValuedHashMap<>(); } // MultiValuedMap Decorators // -----------------------------------------------------------------------
Returns an UnmodifiableMultiValuedMap backed by the given map.
Params:
Type parameters:
  • <K> – the key type
  • <V> – the value type
Throws:
Returns:an unmodifiable MultiValuedMap backed by the provided map
/** * Returns an <code>UnmodifiableMultiValuedMap</code> backed by the given * map. * * @param <K> the key type * @param <V> the value type * @param map the {@link MultiValuedMap} to decorate, must not be null * @return an unmodifiable {@link MultiValuedMap} backed by the provided map * @throws NullPointerException if map is null */
public static <K, V> MultiValuedMap<K, V> unmodifiableMultiValuedMap( final MultiValuedMap<? extends K, ? extends V> map) { return UnmodifiableMultiValuedMap.<K, V>unmodifiableMultiValuedMap(map); }
Returns a TransformedMultiValuedMap backed by the given map.

This method returns a new MultiValuedMap (decorating the specified map) that will transform any new entries added to it. Existing entries in the specified map will not be transformed. If you want that behaviour, see TransformedMultiValuedMap.transformedMap.

Each object is passed through the transformers as it is added to the Map. It is important not to use the original map after invoking this method, as it is a back door for adding untransformed objects.

If there are any elements already in the map being decorated, they are NOT transformed.

Params:
  • map – the MultiValuedMap to transform, must not be null, typically empty
  • keyTransformer – the transformer for the map keys, null means no transformation
  • valueTransformer – the transformer for the map values, null means no transformation
Type parameters:
  • <K> – the key type
  • <V> – the value type
Throws:
Returns:a transformed MultiValuedMap backed by the given map
/** * Returns a <code>TransformedMultiValuedMap</code> backed by the given map. * <p> * This method returns a new <code>MultiValuedMap</code> (decorating the * specified map) that will transform any new entries added to it. Existing * entries in the specified map will not be transformed. If you want that * behaviour, see {@link TransformedMultiValuedMap#transformedMap}. * <p> * Each object is passed through the transformers as it is added to the Map. * It is important not to use the original map after invoking this method, * as it is a back door for adding untransformed objects. * <p> * If there are any elements already in the map being decorated, they are * NOT transformed. * * @param <K> the key type * @param <V> the value type * @param map the {@link MultiValuedMap} to transform, must not be null, typically empty * @param keyTransformer the transformer for the map keys, null means no transformation * @param valueTransformer the transformer for the map values, null means no transformation * @return a transformed <code>MultiValuedMap</code> backed by the given map * @throws NullPointerException if map is null */
public static <K, V> MultiValuedMap<K, V> transformedMultiValuedMap(final MultiValuedMap<K, V> map, final Transformer<? super K, ? extends K> keyTransformer, final Transformer<? super V, ? extends V> valueTransformer) { return TransformedMultiValuedMap.transformingMap(map, keyTransformer, valueTransformer); } }