    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      https://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017package org.apache.commons.collections4;
    018
    019import java.io.PrintStream;
    020import java.text.NumberFormat;
    021import java.text.ParseException;
    022import java.util.ArrayDeque;
    023import java.util.Collection;
    024import java.util.Collections;
    025import java.util.Deque;
    026import java.util.Enumeration;
    027import java.util.HashMap;
    028import java.util.Map;
    029import java.util.Map.Entry;
    030import java.util.Objects;
    031import java.util.Properties;
    032import java.util.ResourceBundle;
    033import java.util.SortedMap;
    034import java.util.TreeMap;
    035import java.util.function.BiFunction;
    036import java.util.function.Function;
    037
    038import org.apache.commons.collections4.map.AbstractMapDecorator;
    039import org.apache.commons.collections4.map.AbstractSortedMapDecorator;
    040import org.apache.commons.collections4.map.FixedSizeMap;
    041import org.apache.commons.collections4.map.FixedSizeSortedMap;
    042import org.apache.commons.collections4.map.LazyMap;
    043import org.apache.commons.collections4.map.LazySortedMap;
    044import org.apache.commons.collections4.map.ListOrderedMap;
    045import org.apache.commons.collections4.map.MultiValueMap;
    046import org.apache.commons.collections4.map.PredicatedMap;
    047import org.apache.commons.collections4.map.PredicatedSortedMap;
    048import org.apache.commons.collections4.map.TransformedMap;
    049import org.apache.commons.collections4.map.TransformedSortedMap;
    050import org.apache.commons.collections4.map.UnmodifiableMap;
    051import org.apache.commons.collections4.map.UnmodifiableSortedMap;
    052
    053/**
    054 * Provides utility methods and decorators for {@link Map} and {@link SortedMap} instances.
    055 * <p>
    056 * It contains various type safe methods as well as other useful features like deep copying.
    057 * </p>
    058 * <p>
    059 * It also provides the following decorators:
    060 * </p>
    061 *
    062 * <ul>
    063 * <li>{@link #fixedSizeMap(Map)}</li>
    064 * <li>{@link #fixedSizeSortedMap(SortedMap)}</li>
    065 * <li>{@link #lazyMap(Map,Factory)}</li>
    066 * <li>{@link #lazyMap(Map,Transformer)}</li>
    067 * <li>{@link #lazySortedMap(SortedMap,Factory)}</li>
    068 * <li>{@link #lazySortedMap(SortedMap,Transformer)}</li>
    069 * <li>{@link #predicatedMap(Map,Predicate,Predicate)}</li>
    070 * <li>{@link #predicatedSortedMap(SortedMap,Predicate,Predicate)}</li>
    071 * <li>{@link #transformedMap(Map, Transformer, Transformer)}</li>
    072 * <li>{@link #transformedSortedMap(SortedMap, Transformer, Transformer)}</li>
    073 * <li>{@link #multiValueMap(Map)}</li>
    074 * <li>{@link #multiValueMap(Map, Class)}</li>
    075 * <li>{@link #multiValueMap(Map, Factory)}</li>
    076 * </ul>
    077 *
    078 * @since 1.0
    079 */
    080@SuppressWarnings("deprecation")
    081public class MapUtils {
    082
    083    /**
    084     * An empty unmodifiable sorted map. This is not provided in the JDK.
    085     */
    086    @SuppressWarnings("rawtypes")
    087    public static final SortedMap EMPTY_SORTED_MAP = UnmodifiableSortedMap.unmodifiableSortedMap(new TreeMap<>());
    088
    089    /**
    090     * String used to indent the verbose and debug Map prints.
    091     */
    092    private static final String INDENT_STRING = "    ";
    093
    094    /**
    095     * Applies the {@code getFunction} and returns its result if non-null, if null returns the result of applying the
    096     * default function.
    097     *
    098     * @param <K> The key type.
    099     * @param <R> The result type.
    100     * @param map The map to query.
    101     * @param key The key into the map.
    102     * @param getFunction The get function.
    103     * @param defaultFunction The function to provide a default value.
    104     * @return The result of applying a function.
    105     */
    106    private static <K, R> R applyDefaultFunction(final Map<? super K, ?> map, final K key,
    107            final BiFunction<Map<? super K, ?>, K, R> getFunction, final Function<K, R> defaultFunction) {
    108        return applyDefaultFunction(map, key, getFunction, defaultFunction, null);
    109    }
    110
    111    /**
    112     * Applies the {@code getFunction} and returns its result if non-null, if null returns the result of applying the
    113     * default function.
    114     *
    115     * @param <K> The key type.
    116     * @param <R> The result type.
    117     * @param map The map to query.
    118     * @param key The key into the map.
    119     * @param getFunction The get function.
    120     * @param defaultFunction The function to provide a default value.
    121     * @param defaultValue The default value.
    122     * @return The result of applying a function.
    123     */
    124    private static <K, R> R applyDefaultFunction(final Map<? super K, ?> map, final K key,
    125            final BiFunction<Map<? super K, ?>, K, R> getFunction, final Function<K, R> defaultFunction,
    126            final R defaultValue) {
    127        R value = map != null && getFunction != null ? getFunction.apply(map, key) : null;
    128        if (value == null) {
    129            value = defaultFunction != null ? defaultFunction.apply(key) : null;
    130        }
    131        return value != null ? value : defaultValue;
    132    }
    133
    134    /**
    135     * Applies the {@code getFunction} and returns its result if non-null, if null returns the {@code defaultValue}.
    136     *
    137     * @param <K> The key type.
    138     * @param <R> The result type.
    139     * @param map The map to query.
    140     * @param key The key into the map.
    141     * @param getFunction The get function.
    142     * @param defaultValue The default value.
    143     * @return The result of applying a function.
    144     */
    145    private static <K, R> R applyDefaultValue(final Map<? super K, ?> map, final K key,
    146            final BiFunction<Map<? super K, ?>, K, R> getFunction, final R defaultValue) {
    147        final R value = map != null && getFunction != null ? getFunction.apply(map, key) : null;
    148        return value == null ? defaultValue : value;
    149    }
    150
    151    private static int calculateHashMapCapacity(final int numMappings) {
    152        return (int) Math.ceil(numMappings / 0.75d);
    153    }
    154
    155    /**
    156     * Prints the given map with nice line breaks.
    157     * <p>
    158     * This method prints a nicely formatted String describing the Map. Each map entry will be printed with key, value
    159     * and value class name. When the value is a Map, recursive behavior occurs.
    160     * </p>
    161     * <p>
    162     * This method is NOT thread-safe in any special way. You must manually synchronize on either this class or the
    163     * stream as required.
    164     * </p>
    165     *
    166     * @param out The stream to print to, must not be null
    167     * @param label The label to be used, may be {@code null}. If {@code null}, the label is not output. It
    168     *        typically represents the name of the property in a bean or similar.
    169     * @param map The map to print, may be {@code null}. If {@code null}, the text 'null' is output.
    170     * @throws NullPointerException if the stream is {@code null}
    171     */
    172    public static void debugPrint(final PrintStream out, final Object label, final Map<?, ?> map) {
    173        verbosePrintInternal(out, label, map, new ArrayDeque<>(), true);
    174    }
    175
    176    /**
    177     * Returns an immutable empty map if the argument is {@code null}, or the argument itself otherwise.
    178     *
    179     * @param <K> The key type
    180     * @param <V> The value type
    181     * @param map The map, possibly {@code null}
    182     * @return An empty map if the argument is {@code null}
    183     */
    184    public static <K, V> Map<K, V> emptyIfNull(final Map<K, V> map) {
    185        return map == null ? Collections.<K, V>emptyMap() : map;
    186    }
    187
    188    /**
    189     * Returns a fixed-sized map backed by the given map. Elements may not be added or removed from the returned map,
    190     * but existing elements can be changed (for instance, via the {@link Map#put(Object,Object)} method).
    191     *
    192     * @param <K> The key type
    193     * @param <V> The value type
    194     * @param map The map whose size to fix, must not be null
    195     * @return A fixed-size map backed by that map
    196     * @throws NullPointerException if the Map is null
    197     */
    198    public static <K, V> IterableMap<K, V> fixedSizeMap(final Map<K, V> map) {
    199        return FixedSizeMap.fixedSizeMap(map);
    200    }
    201
    202    /**
    203     * Returns a fixed-sized sorted map backed by the given sorted map. Elements may not be added or removed from the
    204     * returned map, but existing elements can be changed (for instance, via the {@link Map#put(Object,Object)} method).
    205     *
    206     * @param <K> The key type
    207     * @param <V> The value type
    208     * @param map The map whose size to fix, must not be null
    209     * @return A fixed-size map backed by that map
    210     * @throws NullPointerException if the SortedMap is null
    211     */
    212    public static <K, V> SortedMap<K, V> fixedSizeSortedMap(final SortedMap<K, V> map) {
    213        return FixedSizeSortedMap.fixedSizeSortedMap(map);
    214    }
    215
    216    /**
    217     * Gets a Boolean from a Map in a null-safe manner.
    218     * <p>
    219     * If the value is a {@code Boolean} it is returned directly. If the value is a {@code String} and it
    220     * equals 'true' ignoring case then {@code true} is returned, otherwise {@code false}. If the value is a
    221     * {@code Number} an integer zero value returns {@code false} and non-zero returns {@code true}.
    222     * Otherwise, {@code null} is returned.
    223     * </p>
    224     *
    225     * @param <K> The key type
    226     * @param map The map to use
    227     * @param key The key to look up
    228     * @return The value in the Map as a Boolean, {@code null} if null map input
    229     */
    230    public static <K> Boolean getBoolean(final Map<? super K, ?> map, final K key) {
    231        if (map != null) {
    232            final Object answer = map.get(key);
    233            if (answer != null) {
    234                if (answer instanceof Boolean) {
    235                    return (Boolean) answer;
    236                }
    237                if (answer instanceof String) {
    238                    return Boolean.valueOf((String) answer);
    239                }
    240                if (answer instanceof Number) {
    241                    final Number n = (Number) answer;
    242                    return n.intValue() != 0 ? Boolean.TRUE : Boolean.FALSE;
    243                }
    244            }
    245        }
    246        return null;
    247    }
    248
    249    /**
    250     * Looks up the given key in the given map, converting the result into a boolean, using the default value if the
    251     * conversion fails.
    252     *
    253     * @param <K> The key type
    254     * @param map The map whose value to look up
    255     * @param key The key of the value to look up in that map
    256     * @param defaultValue what to return if the value is null or if the conversion fails
    257     * @return The value in the map as a boolean, or defaultValue if the original value is null, the map is null or the
    258     *         boolean conversion fails
    259     */
    260    public static <K> Boolean getBoolean(final Map<? super K, ?> map, final K key, final Boolean defaultValue) {
    261        return applyDefaultValue(map, key, MapUtils::getBoolean, defaultValue);
    262    }
    263
    264    /**
    265     * Looks up the given key in the given map, converting the result into a boolean, using the defaultFunction to
    266     * produce the default value if the conversion fails.
    267     *
    268     * @param <K> The key type
    269     * @param map The map whose value to look up
    270     * @param key The key of the value to look up in that map
    271     * @param defaultFunction what to produce the default value if the value is null or if the conversion fails
    272     * @return The value in the map as a boolean, or defaultValue produced by the defaultFunction if the original value
    273     *         is null, the map is null or the boolean conversion fails
    274     * @since 4.5.0-M1
    275     */
    276    public static <K> Boolean getBoolean(final Map<? super K, ?> map, final K key,
    277            final Function<K, Boolean> defaultFunction) {
    278        return applyDefaultFunction(map, key, MapUtils::getBoolean, defaultFunction);
    279    }
    280
    281    /**
    282     * Gets a boolean from a Map in a null-safe manner.
    283     * <p>
    284     * If the value is a {@code Boolean} its value is returned. If the value is a {@code String} and it equals
    285     * 'true' ignoring case then {@code true} is returned, otherwise {@code false}. If the value is a
    286     * {@code Number} an integer zero value returns {@code false} and non-zero returns {@code true}.
    287     * Otherwise, {@code false} is returned.
    288     * </p>
    289     *
    290     * @param <K> The key type
    291     * @param map The map to use
    292     * @param key The key to look up
    293     * @return The value in the Map as a Boolean, {@code false} if null map input
    294     */
    295    public static <K> boolean getBooleanValue(final Map<? super K, ?> map, final K key) {
    296        return Boolean.TRUE.equals(getBoolean(map, key));
    297    }
    298
    299    /**
    300     * Gets a boolean from a Map in a null-safe manner, using the default value if the conversion fails.
    301     * <p>
    302     * If the value is a {@code Boolean} its value is returned. If the value is a {@code String} and it equals
    303     * 'true' ignoring case then {@code true} is returned, otherwise {@code false}. If the value is a
    304     * {@code Number} an integer zero value returns {@code false} and non-zero returns {@code true}.
    305     * Otherwise, {@code defaultValue} is returned.
    306     * </p>
    307     *
    308     * @param <K> The key type
    309     * @param map The map to use
    310     * @param key The key to look up
    311     * @param defaultValue return if the value is null or if the conversion fails
    312     * @return The value in the Map as a Boolean, {@code defaultValue} if null map input
    313     */
    314    public static <K> boolean getBooleanValue(final Map<? super K, ?> map, final K key, final boolean defaultValue) {
    315        return applyDefaultValue(map, key, MapUtils::getBoolean, defaultValue).booleanValue();
    316    }
    317
    318    /**
    319     * Gets a boolean from a Map in a null-safe manner, using the default value produced by the defaultFunction if the
    320     * conversion fails.
    321     * <p>
    322     * If the value is a {@code Boolean} its value is returned. If the value is a {@code String} and it equals
    323     * 'true' ignoring case then {@code true} is returned, otherwise {@code false}. If the value is a
    324     * {@code Number} an integer zero value returns {@code false} and non-zero returns {@code true}.
    325     * Otherwise, defaultValue produced by the {@code defaultFunction} is returned.
    326     * </p>
    327     *
    328     * @param <K> The key type
    329     * @param map The map to use
    330     * @param key The key to look up
    331     * @param defaultFunction produce the default value to return if the value is null or if the conversion fails
    332     * @return The value in the Map as a Boolean, default value produced by the {@code defaultFunction} if null map
    333     *         input
    334     * @since 4.5.0-M1
    335     */
    336    public static <K> boolean getBooleanValue(final Map<? super K, ?> map, final K key,
    337            final Function<K, Boolean> defaultFunction) {
    338        return applyDefaultFunction(map, key, MapUtils::getBoolean, defaultFunction, false).booleanValue();
    339    }
    340
    341    /**
    342     * Gets a Byte from a Map in a null-safe manner.
    343     * <p>
    344     * The Byte is obtained from the results of {@link #getNumber(Map,Object)}.
    345     * </p>
    346     *
    347     * @param <K> The key type
    348     * @param map The map to use
    349     * @param key The key to look up
    350     * @return The value in the Map as a Byte, {@code null} if null map input
    351     */
    352    public static <K> Byte getByte(final Map<? super K, ?> map, final K key) {
    353        final Number answer = getNumber(map, key);
    354        if (answer == null) {
    355            return null;
    356        }
    357        if (answer instanceof Byte) {
    358            return (Byte) answer;
    359        }
    360        return Byte.valueOf(answer.byteValue());
    361    }
    362
    363    /**
    364     * Looks up the given key in the given map, converting the result into a byte, using the default value if the
    365     * conversion fails.
    366     *
    367     * @param <K> The key type
    368     * @param map The map whose value to look up
    369     * @param key The key of the value to look up in that map
    370     * @param defaultValue what to return if the value is null or if the conversion fails
    371     * @return The value in the map as a number, or defaultValue if the original value is null, the map is null or the
    372     *         number conversion fails
    373     */
    374    public static <K> Byte getByte(final Map<? super K, ?> map, final K key, final Byte defaultValue) {
    375        return applyDefaultValue(map, key, MapUtils::getByte, defaultValue);
    376    }
    377
    378    /**
    379     * Looks up the given key in the given map, converting the result into a byte, using the defaultFunction to produce
    380     * the default value if the conversion fails.
    381     *
    382     * @param <K> The key type
    383     * @param map The map whose value to look up
    384     * @param key The key of the value to look up in that map
    385     * @param defaultFunction what to produce the default value if the value is null or if the conversion fails
    386     * @return The value in the map as a number, or defaultValue produced by the defaultFunction if the original value
    387     *         is null, the map is null or the number conversion fails
    388     * @since 4.5.0-M1
    389     */
    390    public static <K> Byte getByte(final Map<? super K, ?> map, final K key, final Function<K, Byte> defaultFunction) {
    391        return applyDefaultFunction(map, key, MapUtils::getByte, defaultFunction);
    392    }
    393
    394    /**
    395     * Gets a byte from a Map in a null-safe manner.
    396     * <p>
    397     * The byte is obtained from the results of {@link #getNumber(Map,Object)}.
    398     * </p>
    399     *
    400     * @param <K> The key type
    401     * @param map The map to use
    402     * @param key The key to look up
    403     * @return The value in the Map as a byte, {@code 0} if null map input
    404     */
    405    public static <K> byte getByteValue(final Map<? super K, ?> map, final K key) {
    406        return applyDefaultValue(map, key, MapUtils::getByte, 0).byteValue();
    407    }
    408
    409    /**
    410     * Gets a byte from a Map in a null-safe manner, using the default value if the conversion fails.
    411     * <p>
    412     * The byte is obtained from the results of {@link #getNumber(Map,Object)}.
    413     * </p>
    414     *
    415     * @param <K> The key type
    416     * @param map The map to use
    417     * @param key The key to look up
    418     * @param defaultValue return if the value is null or if the conversion fails
    419     * @return The value in the Map as a byte, {@code defaultValue} if null map input
    420     */
    421    public static <K> byte getByteValue(final Map<? super K, ?> map, final K key, final byte defaultValue) {
    422        return applyDefaultValue(map, key, MapUtils::getByte, defaultValue).byteValue();
    423    }
    424
    425    /**
    426     * Gets a byte from a Map in a null-safe manner, using the default value produced by the defaultFunction if the
    427     * conversion fails.
    428     * <p>
    429     * The byte is obtained from the results of {@link #getNumber(Map,Object)}.
    430     * </p>
    431     *
    432     * @param <K> The key type
    433     * @param map The map to use
    434     * @param key The key to look up
    435     * @param defaultFunction produce the default value to return if the value is null or if the conversion fails
    436     * @return The value in the Map as a byte, default value produced by the {@code defaultFunction} if null map
    437     *         input
    438     * @since 4.5.0-M1
    439     */
    440    public static <K> byte getByteValue(final Map<? super K, ?> map, final K key,
    441            final Function<K, Byte> defaultFunction) {
    442        return applyDefaultFunction(map, key, MapUtils::getByte, defaultFunction, (byte) 0).byteValue();
    443    }
    444
    445    /**
    446     * Gets a Double from a Map in a null-safe manner.
    447     * <p>
    448     * The Double is obtained from the results of {@link #getNumber(Map,Object)}.
    449     * </p>
    450     *
    451     * @param <K> The key type
    452     * @param map The map to use
    453     * @param key The key to look up
    454     * @return The value in the Map as a Double, {@code null} if null map input
    455     */
    456    public static <K> Double getDouble(final Map<? super K, ?> map, final K key) {
    457        final Number answer = getNumber(map, key);
    458        if (answer == null) {
    459            return null;
    460        }
    461        if (answer instanceof Double) {
    462            return (Double) answer;
    463        }
    464        return Double.valueOf(answer.doubleValue());
    465    }
    466
    467    /**
    468     * Looks up the given key in the given map, converting the result into a double, using the default value if the
    469     * conversion fails.
    470     *
    471     * @param <K> The key type
    472     * @param map The map whose value to look up
    473     * @param key The key of the value to look up in that map
    474     * @param defaultValue what to return if the value is null or if the conversion fails
    475     * @return The value in the map as a number, or defaultValue if the original value is null, the map is null or the
    476     *         number conversion fails
    477     */
    478    public static <K> Double getDouble(final Map<? super K, ?> map, final K key, final Double defaultValue) {
    479        return applyDefaultValue(map, key, MapUtils::getDouble, defaultValue);
    480    }
    481
    482    /**
    483     * Looks up the given key in the given map, converting the result into a double, using the defaultFunction to
    484     * produce the default value if the conversion fails.
    485     *
    486     * @param <K> The key type
    487     * @param map The map whose value to look up
    488     * @param key The key of the value to look up in that map
    489     * @param defaultFunction what to produce the default value if the value is null or if the conversion fails
    490     * @return The value in the map as a number, or defaultValue produced by the defaultFunction if the original value
    491     *         is null, the map is null or the number conversion fails
    492     * @since 4.5.0-M1
    493     */
    494    public static <K> Double getDouble(final Map<? super K, ?> map, final K key,
    495            final Function<K, Double> defaultFunction) {
    496        return applyDefaultFunction(map, key, MapUtils::getDouble, defaultFunction);
    497    }
    498
    499    /**
    500     * Gets a double from a Map in a null-safe manner.
    501     * <p>
    502     * The double is obtained from the results of {@link #getNumber(Map,Object)}.
    503     * </p>
    504     *
    505     * @param <K> The key type
    506     * @param map The map to use
    507     * @param key The key to look up
    508     * @return The value in the Map as a double, {@code 0.0} if null map input
    509     */
    510    public static <K> double getDoubleValue(final Map<? super K, ?> map, final K key) {
    511        return applyDefaultValue(map, key, MapUtils::getDouble, 0d).doubleValue();
    512    }
    513
    514    /**
    515     * Gets a double from a Map in a null-safe manner, using the default value if the conversion fails.
    516     * <p>
    517     * The double is obtained from the results of {@link #getNumber(Map,Object)}.
    518     * </p>
    519     *
    520     * @param <K> The key type
    521     * @param map The map to use
    522     * @param key The key to look up
    523     * @param defaultValue return if the value is null or if the conversion fails
    524     * @return The value in the Map as a double, {@code defaultValue} if null map input
    525     */
    526    public static <K> double getDoubleValue(final Map<? super K, ?> map, final K key, final double defaultValue) {
    527        return applyDefaultValue(map, key, MapUtils::getDouble, defaultValue).doubleValue();
    528    }
    529
    530    /**
    531     * Gets a double from a Map in a null-safe manner, using the default value produced by the defaultFunction if the
    532     * conversion fails.
    533     * <p>
    534     * The double is obtained from the results of {@link #getNumber(Map,Object)}.
    535     * </p>
    536     *
    537     * @param <K> The key type
    538     * @param map The map to use
    539     * @param key The key to look up
    540     * @param defaultFunction produce the default value to return if the value is null or if the conversion fails
    541     * @return The value in the Map as a double, default value produced by the {@code defaultFunction} if null map
    542     *         input
    543     * @since 4.5.0-M1
    544     */
    545    public static <K> double getDoubleValue(final Map<? super K, ?> map, final K key,
    546            final Function<K, Double> defaultFunction) {
    547        return applyDefaultFunction(map, key, MapUtils::getDouble, defaultFunction, 0d).doubleValue();
    548    }
    549
    550    /**
    551     * Gets a Float from a Map in a null-safe manner.
    552     * <p>
    553     * The Float is obtained from the results of {@link #getNumber(Map,Object)}.
    554     * </p>
    555     *
    556     * @param <K> The key type
    557     * @param map The map to use
    558     * @param key The key to look up
    559     * @return The value in the Map as a Float, {@code null} if null map input
    560     */
    561    public static <K> Float getFloat(final Map<? super K, ?> map, final K key) {
    562        final Number answer = getNumber(map, key);
    563        if (answer == null) {
    564            return null;
    565        }
    566        if (answer instanceof Float) {
    567            return (Float) answer;
    568        }
    569        return Float.valueOf(answer.floatValue());
    570    }
    571
    572    /**
    573     * Looks up the given key in the given map, converting the result into a float, using the default value if the
    574     * conversion fails.
    575     *
    576     * @param <K> The key type
    577     * @param map The map whose value to look up
    578     * @param key The key of the value to look up in that map
    579     * @param defaultValue what to return if the value is null or if the conversion fails
    580     * @return The value in the map as a number, or defaultValue if the original value is null, the map is null or the
    581     *         number conversion fails
    582     */
    583    public static <K> Float getFloat(final Map<? super K, ?> map, final K key, final Float defaultValue) {
    584        return applyDefaultValue(map, key, MapUtils::getFloat, defaultValue);
    585    }
    586
    587    /**
    588     * Looks up the given key in the given map, converting the result into a float, using the defaultFunction to produce
    589     * the default value if the conversion fails.
    590     *
    591     * @param <K> The key type
    592     * @param map The map whose value to look up
    593     * @param key The key of the value to look up in that map
    594     * @param defaultFunction what to produce the default value if the value is null or if the conversion fails
    595     * @return The value in the map as a number, or defaultValue produced by the defaultFunction if the original value
    596     *         is null, the map is null or the number conversion fails
    597     * @since 4.5.0-M1
    598     */
    599    public static <K> Float getFloat(final Map<? super K, ?> map, final K key,
    600            final Function<K, Float> defaultFunction) {
    601        return applyDefaultFunction(map, key, MapUtils::getFloat, defaultFunction);
    602    }
    603
    604    /**
    605     * Gets a float from a Map in a null-safe manner.
    606     * <p>
    607     * The float is obtained from the results of {@link #getNumber(Map,Object)}.
    608     * </p>
    609     *
    610     * @param <K> The key type
    611     * @param map The map to use
    612     * @param key The key to look up
    613     * @return The value in the Map as a float, {@code 0.0F} if null map input
    614     */
    615    public static <K> float getFloatValue(final Map<? super K, ?> map, final K key) {
    616        return applyDefaultValue(map, key, MapUtils::getFloat, 0f).floatValue();
    617    }
    618
    619    /**
    620     * Gets a float from a Map in a null-safe manner, using the default value if the conversion fails.
    621     * <p>
    622     * The float is obtained from the results of {@link #getNumber(Map,Object)}.
    623     * </p>
    624     *
    625     * @param <K> The key type
    626     * @param map The map to use
    627     * @param key The key to look up
    628     * @param defaultValue return if the value is null or if the conversion fails
    629     * @return The value in the Map as a float, {@code defaultValue} if null map input
    630     */
    631    public static <K> float getFloatValue(final Map<? super K, ?> map, final K key, final float defaultValue) {
    632        return applyDefaultValue(map, key, MapUtils::getFloat, defaultValue).floatValue();
    633    }
    634
    635    /**
    636     * Gets a float from a Map in a null-safe manner, using the default value produced by the defaultFunction if the
    637     * conversion fails.
    638     * <p>
    639     * The float is obtained from the results of {@link #getNumber(Map,Object)}.
    640     * </p>
    641     *
    642     * @param <K> The key type
    643     * @param map The map to use
    644     * @param key The key to look up
    645     * @param defaultFunction produce the default value to return if the value is null or if the conversion fails
    646     * @return The value in the Map as a float, default value produced by the {@code defaultFunction} if null map
    647     *         input
    648     * @since 4.5.0-M1
    649     */
    650    public static <K> float getFloatValue(final Map<? super K, ?> map, final K key,
    651            final Function<K, Float> defaultFunction) {
    652        return applyDefaultFunction(map, key, MapUtils::getFloat, defaultFunction, 0f).floatValue();
    653    }
    654
    655    /**
    656     * Gets an Integer from a Map in a null-safe manner.
    657     * <p>
    658     * The Integer is obtained from the results of {@link #getNumber(Map,Object)}.
    659     * </p>
    660     *
    661     * @param <K> The key type
    662     * @param map The map to use
    663     * @param key The key to look up
    664     * @return The value in the Map as an Integer, {@code null} if null map input
    665     */
    666    public static <K> Integer getInteger(final Map<? super K, ?> map, final K key) {
    667        final Number answer = getNumber(map, key);
    668        if (answer == null) {
    669            return null;
    670        }
    671        if (answer instanceof Integer) {
    672            return (Integer) answer;
    673        }
    674        return Integer.valueOf(answer.intValue());
    675    }
    676
    677    /**
    678     * Looks up the given key in the given map, converting the result into an integer, using the defaultFunction to
    679     * produce the default value if the conversion fails.
    680     *
    681     * @param <K> The key type
    682     * @param map The map whose value to look up
    683     * @param key The key of the value to look up in that map
    684     * @param defaultFunction what to produce the default value if the value is null or if the conversion fails
    685     * @return The value in the map as a number, or defaultValue produced by the defaultFunction if the original value
    686     *         is null, the map is null or the number conversion fails
    687     * @since 4.5.0-M1
    688     */
    689    public static <K> Integer getInteger(final Map<? super K, ?> map, final K key,
    690            final Function<K, Integer> defaultFunction) {
    691        return applyDefaultFunction(map, key, MapUtils::getInteger, defaultFunction);
    692    }
    693
    694    /**
    695     * Looks up the given key in the given map, converting the result into an integer, using the default value if the
    696     * conversion fails.
    697     *
    698     * @param <K> The key type
    699     * @param map The map whose value to look up
    700     * @param key The key of the value to look up in that map
    701     * @param defaultValue what to return if the value is null or if the conversion fails
    702     * @return The value in the map as a number, or defaultValue if the original value is null, the map is null or the
    703     *         number conversion fails
    704     */
    705    public static <K> Integer getInteger(final Map<? super K, ?> map, final K key, final Integer defaultValue) {
    706        return applyDefaultValue(map, key, MapUtils::getInteger, defaultValue);
    707    }
    708
    709    /**
    710     * Gets an int from a Map in a null-safe manner.
    711     * <p>
    712     * The int is obtained from the results of {@link #getNumber(Map,Object)}.
    713     * </p>
    714     *
    715     * @param <K> The key type
    716     * @param map The map to use
    717     * @param key The key to look up
    718     * @return The value in the Map as an int, {@code 0} if null map input
    719     */
    720    public static <K> int getIntValue(final Map<? super K, ?> map, final K key) {
    721        return applyDefaultValue(map, key, MapUtils::getInteger, 0).intValue();
    722    }
    723
    724    /**
    725     * Gets an int from a Map in a null-safe manner, using the default value produced by the defaultFunction if the
    726     * conversion fails.
    727     * <p>
    728     * The int is obtained from the results of {@link #getNumber(Map,Object)}.
    729     * </p>
    730     *
    731     * @param <K> The key type
    732     * @param map The map to use
    733     * @param key The key to look up
    734     * @param defaultFunction produce the default value to return if the value is null or if the conversion fails
    735     * @return The value in the Map as an int, default value produced by the {@code defaultFunction} if null map
    736     *         input
    737     * @since 4.5.0-M1
    738     */
    739    public static <K> int getIntValue(final Map<? super K, ?> map, final K key,
    740            final Function<K, Integer> defaultFunction) {
    741        return applyDefaultFunction(map, key, MapUtils::getInteger, defaultFunction, 0).intValue();
    742    }
    743
    744    /**
    745     * Gets an int from a Map in a null-safe manner, using the default value if the conversion fails.
    746     * <p>
    747     * The int is obtained from the results of {@link #getNumber(Map,Object)}.
    748     * </p>
    749     *
    750     * @param <K> The key type
    751     * @param map The map to use
    752     * @param key The key to look up
    753     * @param defaultValue return if the value is null or if the conversion fails
    754     * @return The value in the Map as an int, {@code defaultValue} if null map input
    755     */
    756    public static <K> int getIntValue(final Map<? super K, ?> map, final K key, final int defaultValue) {
    757        return applyDefaultValue(map, key, MapUtils::getInteger, defaultValue).intValue();
    758    }
    759
    760    /**
    761     * Gets a Long from a Map in a null-safe manner.
    762     * <p>
    763     * The Long is obtained from the results of {@link #getNumber(Map,Object)}.
    764     * </p>
    765     *
    766     * @param <K> The key type
    767     * @param map The map to use
    768     * @param key The key to look up
    769     * @return The value in the Map as a Long, {@code null} if null map input
    770     */
    771    public static <K> Long getLong(final Map<? super K, ?> map, final K key) {
    772        final Number answer = getNumber(map, key);
    773        if (answer == null) {
    774            return null;
    775        }
    776        if (answer instanceof Long) {
    777            return (Long) answer;
    778        }
    779        return Long.valueOf(answer.longValue());
    780    }
    781
    782    /**
    783     * Looks up the given key in the given map, converting the result into a Long, using the defaultFunction to produce
    784     * the default value if the conversion fails.
    785     *
    786     * @param <K> The key type
    787     * @param map The map whose value to look up
    788     * @param key The key of the value to look up in that map
    789     * @param defaultFunction what to produce the default value if the value is null or if the conversion fails
    790     * @return The value in the map as a number, or defaultValue produced by the defaultFunction if the original value
    791     *         is null, the map is null or the number conversion fails
    792     * @since 4.5.0-M1
    793     */
    794    public static <K> Long getLong(final Map<? super K, ?> map, final K key, final Function<K, Long> defaultFunction) {
    795        return applyDefaultFunction(map, key, MapUtils::getLong, defaultFunction);
    796    }
    797
    798    /**
    799     * Looks up the given key in the given map, converting the result into a long, using the default value if the
    800     * conversion fails.
    801     *
    802     * @param <K> The key type
    803     * @param map The map whose value to look up
    804     * @param key The key of the value to look up in that map
    805     * @param defaultValue what to return if the value is null or if the conversion fails
    806     * @return The value in the map as a number, or defaultValue if the original value is null, the map is null or the
    807     *         number conversion fails
    808     */
    809    public static <K> Long getLong(final Map<? super K, ?> map, final K key, final Long defaultValue) {
    810        return applyDefaultValue(map, key, MapUtils::getLong, defaultValue);
    811    }
    812
    813    /**
    814     * Gets a long from a Map in a null-safe manner.
    815     * <p>
    816     * The long is obtained from the results of {@link #getNumber(Map,Object)}.
    817     * </p>
    818     *
    819     * @param <K> The key type
    820     * @param map The map to use
    821     * @param key The key to look up
    822     * @return The value in the Map as a long, {@code 0L} if null map input
    823     */
    824    public static <K> long getLongValue(final Map<? super K, ?> map, final K key) {
    825        return applyDefaultValue(map, key, MapUtils::getLong, 0L).longValue();
    826    }
    827
    828    /**
    829     * Gets a long from a Map in a null-safe manner, using the default value produced by the defaultFunction if the
    830     * conversion fails.
    831     * <p>
    832     * The long is obtained from the results of {@link #getNumber(Map,Object)}.
    833     * </p>
    834     *
    835     * @param <K> The key type
    836     * @param map The map to use
    837     * @param key The key to look up
    838     * @param defaultFunction produce the default value to return if the value is null or if the conversion fails
    839     * @return The value in the Map as a long, default value produced by the {@code defaultFunction} if null map
    840     *         input
    841     * @since 4.5.0-M1
    842     */
    843    public static <K> long getLongValue(final Map<? super K, ?> map, final K key,
    844            final Function<K, Long> defaultFunction) {
    845        return applyDefaultFunction(map, key, MapUtils::getLong, defaultFunction, 0L).longValue();
    846    }
    847
    848    /**
    849     * Gets a long from a Map in a null-safe manner, using the default value if the conversion fails.
    850     * <p>
    851     * The long is obtained from the results of {@link #getNumber(Map,Object)}.
    852     * </p>
    853     *
    854     * @param <K> The key type
    855     * @param map The map to use
    856     * @param key The key to look up
    857     * @param defaultValue return if the value is null or if the conversion fails
    858     * @return The value in the Map as a long, {@code defaultValue} if null map input
    859     */
    860    public static <K> long getLongValue(final Map<? super K, ?> map, final K key, final long defaultValue) {
    861        return applyDefaultValue(map, key, MapUtils::getLong, defaultValue).longValue();
    862    }
    863
    864    /**
    865     * Gets a Map from a Map in a null-safe manner.
    866     * <p>
    867     * If the value returned from the specified map is not a Map then {@code null} is returned.
    868     * </p>
    869     *
    870     * @param <K> The key type
    871     * @param map The map to use
    872     * @param key The key to look up
    873     * @return The value in the Map as a Map, {@code null} if null map input
    874     */
    875    public static <K> Map<?, ?> getMap(final Map<? super K, ?> map, final K key) {
    876        if (map != null) {
    877            final Object answer = map.get(key);
    878            if (answer instanceof Map) {
    879                return (Map<?, ?>) answer;
    880            }
    881        }
    882        return null;
    883    }
    884
    885    /**
    886     * Looks up the given key in the given map, converting the result into a map, using the defaultFunction to produce
    887     * the default value if the conversion fails.
    888     *
    889     * @param <K> The key type
    890     * @param map The map whose value to look up
    891     * @param key The key of the value to look up in that map
    892     * @param defaultFunction what to produce the default value if the value is null or if the conversion fails
    893     * @return The value in the map as a number, or defaultValue produced by the defaultFunction if the original value
    894     *         is null, the map is null or the map conversion fails
    895     * @since 4.5.0-M1
    896     */
    897    public static <K> Map<?, ?> getMap(final Map<? super K, ?> map, final K key,
    898            final Function<K, Map<?, ?>> defaultFunction) {
    899        return applyDefaultFunction(map, key, MapUtils::getMap, defaultFunction);
    900    }
    901
    902    /**
    903     * Looks up the given key in the given map, converting the result into a map, using the default value if the
    904     * conversion fails.
    905     *
    906     * @param <K> The key type
    907     * @param map The map whose value to look up
    908     * @param key The key of the value to look up in that map
    909     * @param defaultValue what to return if the value is null or if the conversion fails
    910     * @return The value in the map as a number, or defaultValue if the original value is null, the map is null or the
    911     *         map conversion fails
    912     */
    913    public static <K> Map<?, ?> getMap(final Map<? super K, ?> map, final K key, final Map<?, ?> defaultValue) {
    914        return applyDefaultValue(map, key, MapUtils::getMap, defaultValue);
    915    }
    916
    917    /**
    918     * Gets a Number from a Map in a null-safe manner.
    919     * <p>
    920     * If the value is a {@code Number} it is returned directly. If the value is a {@code String} it is
    921     * converted using {@link NumberFormat#parse(String)} on the system default formatter returning {@code null} if
    922     * the conversion fails. Otherwise, {@code null} is returned.
    923     * </p>
    924     *
    925     * @param <K> The key type
    926     * @param map The map to use
    927     * @param key The key to look up
    928     * @return The value in the Map as a Number, {@code null} if null map input
    929     */
    930    public static <K> Number getNumber(final Map<? super K, ?> map, final K key) {
    931        if (map != null) {
    932            final Object answer = map.get(key);
    933            if (answer != null) {
    934                if (answer instanceof Number) {
    935                    return (Number) answer;
    936                }
    937                if (answer instanceof String) {
    938                    try {
    939                        final String text = (String) answer;
    940                        return NumberFormat.getInstance().parse(text);
    941                    } catch (final ParseException e) { // NOPMD
    942                        // failure means null is returned
    943                    }
    944                }
    945            }
    946        }
    947        return null;
    948    }
    949
    950    /**
    951     * Looks up the given key in the given map, converting the result into a number, using the defaultFunction to
    952     * produce the default value if the conversion fails.
    953     *
    954     * @param <K> The key type
    955     * @param map The map whose value to look up
    956     * @param key The key of the value to look up in that map
    957     * @param defaultFunction what to produce the default value if the value is null or if the conversion fails
    958     * @return The value in the map as a number, or defaultValue produced by the defaultFunction if the original value
    959     *         is null, the map is null or the number conversion fails
    960     * @since 4.5.0-M1
    961     */
    962    public static <K> Number getNumber(final Map<? super K, ?> map, final K key,
    963            final Function<K, Number> defaultFunction) {
    964        return applyDefaultFunction(map, key, MapUtils::getNumber, defaultFunction);
    965    }
    966
    967    /**
    968     * Looks up the given key in the given map, converting the result into a number, using the default value if the
    969     * conversion fails.
    970     *
    971     * @param <K> The key type
    972     * @param map The map whose value to look up
    973     * @param key The key of the value to look up in that map
    974     * @param defaultValue what to return if the value is null or if the conversion fails
    975     * @return The value in the map as a number, or defaultValue if the original value is null, the map is null or the
    976     *         number conversion fails
    977     */
    978    public static <K> Number getNumber(final Map<? super K, ?> map, final K key, final Number defaultValue) {
    979        return applyDefaultValue(map, key, MapUtils::getNumber, defaultValue);
    980    }
    981
    982    /**
    983     * Gets from a Map in a null-safe manner.
    984     *
    985     * @param <K> The key type
    986     * @param <V> The value type
    987     * @param map The map to use
    988     * @param key The key to look up
    989     * @return The value in the Map, {@code null} if null map input
    990     */
    991    public static <K, V> V getObject(final Map<? super K, V> map, final K key) {
    992        if (map != null) {
    993            return map.get(key);
    994        }
    995        return null;
    996    }
    997
    998    /**
    999     * Looks up the given key in the given map, converting null into the given default value.
    1000     *
    1001     * @param <K> The key type
    1002     * @param <V> The value type
    1003     * @param map The map whose value to look up
    1004     * @param key The key of the value to look up in that map
    1005     * @param defaultValue what to return if the value is null
    1006     * @return The value in the map, or defaultValue if the original value is null or the map is null
    1007     */
    1008    public static <K, V> V getObject(final Map<K, V> map, final K key, final V defaultValue) {
    1009        if (map != null) {
    1010            final V answer = map.get(key);
    1011            if (answer != null) {
    1012                return answer;
    1013            }
    1014        }
    1015        return defaultValue;
    1016    }
    1017
    1018    /**
    1019     * Gets a Short from a Map in a null-safe manner.
    1020     * <p>
    1021     * The Short is obtained from the results of {@link #getNumber(Map,Object)}.
    1022     * </p>
    1023     *
    1024     * @param <K> The key type
    1025     * @param map The map to use
    1026     * @param key The key to look up
    1027     * @return The value in the Map as a Short, {@code null} if null map input
    1028     */
    1029    public static <K> Short getShort(final Map<? super K, ?> map, final K key) {
    1030        final Number answer = getNumber(map, key);
    1031        if (answer == null) {
    1032            return null;
    1033        }
    1034        if (answer instanceof Short) {
    1035            return (Short) answer;
    1036        }
    1037        return Short.valueOf(answer.shortValue());
    1038    }
    1039
    1040    /**
    1041     * Looks up the given key in the given map, converting the result into a short, using the defaultFunction to produce
    1042     * the default value if the conversion fails.
    1043     *
    1044     * @param <K> The key type
    1045     * @param map The map whose value to look up
    1046     * @param key The key of the value to look up in that map
    1047     * @param defaultFunction what to produce the default value if the value is null or if the conversion fails
    1048     * @return The value in the map as a number, or defaultValue produced by the defaultFunction if the original value
    1049     *         is null, the map is null or the number conversion fails
    1050     * @since 4.5.0-M1
    1051     */
    1052    public static <K> Short getShort(final Map<? super K, ?> map, final K key,
    1053            final Function<K, Short> defaultFunction) {
    1054        return applyDefaultFunction(map, key, MapUtils::getShort, defaultFunction);
    1055    }
    1056
    1057    /**
    1058     * Looks up the given key in the given map, converting the result into a short, using the default value if the
    1059     * conversion fails.
    1060     *
    1061     * @param <K> The key type
    1062     * @param map The map whose value to look up
    1063     * @param key The key of the value to look up in that map
    1064     * @param defaultValue what to return if the value is null or if the conversion fails
    1065     * @return The value in the map as a number, or defaultValue if the original value is null, the map is null or the
    1066     *         number conversion fails
    1067     */
    1068    public static <K> Short getShort(final Map<? super K, ?> map, final K key, final Short defaultValue) {
    1069        return applyDefaultValue(map, key, MapUtils::getShort, defaultValue);
    1070    }
    1071
    1072    /**
    1073     * Gets a short from a Map in a null-safe manner.
    1074     * <p>
    1075     * The short is obtained from the results of {@link #getNumber(Map,Object)}.
    1076     * </p>
    1077     *
    1078     * @param <K> The key type
    1079     * @param map The map to use
    1080     * @param key The key to look up
    1081     * @return The value in the Map as a short, {@code 0} if null map input
    1082     */
    1083    public static <K> short getShortValue(final Map<? super K, ?> map, final K key) {
    1084        return applyDefaultValue(map, key, MapUtils::getShort, 0).shortValue();
    1085    }
    1086
    1087    /**
    1088     * Gets a short from a Map in a null-safe manner, using the default value produced by the defaultFunction if the
    1089     * conversion fails.
    1090     * <p>
    1091     * The short is obtained from the results of {@link #getNumber(Map,Object)}.
    1092     * </p>
    1093     *
    1094     * @param <K> The key type
    1095     * @param map The map to use
    1096     * @param key The key to look up
    1097     * @param defaultFunction produce the default value to return if the value is null or if the conversion fails
    1098     * @return The value in the Map as a short, default value produced by the {@code defaultFunction} if null map
    1099     *         input
    1100     * @since 4.5.0-M1
    1101     */
    1102    public static <K> short getShortValue(final Map<? super K, ?> map, final K key,
    1103            final Function<K, Short> defaultFunction) {
    1104        return applyDefaultFunction(map, key, MapUtils::getShort, defaultFunction, (short) 0).shortValue();
    1105    }
    1106
    1107    /**
    1108     * Gets a short from a Map in a null-safe manner, using the default value if the conversion fails.
    1109     * <p>
    1110     * The short is obtained from the results of {@link #getNumber(Map,Object)}.
    1111     * </p>
    1112     *
    1113     * @param <K> The key type
    1114     * @param map The map to use
    1115     * @param key The key to look up
    1116     * @param defaultValue return if the value is null or if the conversion fails
    1117     * @return The value in the Map as a short, {@code defaultValue} if null map input
    1118     */
    1119    public static <K> short getShortValue(final Map<? super K, ?> map, final K key, final short defaultValue) {
    1120        return applyDefaultValue(map, key, MapUtils::getShort, defaultValue).shortValue();
    1121    }
    1122
    1123    /**
    1124     * Gets a String from a Map in a null-safe manner.
    1125     * <p>
    1126     * The String is obtained via {@code toString}.
    1127     * </p>
    1128     *
    1129     * @param <K> The key type
    1130     * @param map The map to use
    1131     * @param key The key to look up
    1132     * @return The value in the Map as a String, {@code null} if null map input
    1133     */
    1134    public static <K> String getString(final Map<? super K, ?> map, final K key) {
    1135        if (map != null) {
    1136            final Object answer = map.get(key);
    1137            if (answer != null) {
    1138                return answer.toString();
    1139            }
    1140        }
    1141        return null;
    1142    }
    1143
    1144    /**
    1145     * Looks up the given key in the given map, converting the result into a string, using the defaultFunction to
    1146     * produce the default value if the conversion fails.
    1147     *
    1148     * @param <K> The key type
    1149     * @param map The map whose value to look up
    1150     * @param key The key of the value to look up in that map
    1151     * @param defaultFunction what to produce the default value if the value is null or if the conversion fails
    1152     * @return The value in the map as a string, or defaultValue produced by the defaultFunction if the original value
    1153     *         is null, the map is null or the string conversion fails
    1154     * @since 4.5.0-M1
    1155     */
    1156    public static <K> String getString(final Map<? super K, ?> map, final K key,
    1157            final Function<K, String> defaultFunction) {
    1158        return applyDefaultFunction(map, key, MapUtils::getString, defaultFunction);
    1159    }
    1160
    1161    /**
    1162     * Looks up the given key in the given map, converting the result into a string, using the default value if the
    1163     * conversion fails.
    1164     *
    1165     * @param <K> The key type
    1166     * @param map The map whose value to look up
    1167     * @param key The key of the value to look up in that map
    1168     * @param defaultValue what to return if the value is null or if the conversion fails
    1169     * @return The value in the map as a string, or defaultValue if the original value is null, the map is null or the
    1170     *         string conversion fails
    1171     */
    1172    public static <K> String getString(final Map<? super K, ?> map, final K key, final String defaultValue) {
    1173        return applyDefaultValue(map, key, MapUtils::getString, defaultValue);
    1174    }
    1175
    1176    /**
    1177     * Inverts the supplied map returning a new HashMap such that the keys of the input are swapped with the values.
    1178     * <p>
    1179     * This operation assumes that the inverse mapping is well defined. If the input map had multiple entries with the
    1180     * same value mapped to different keys, the returned map will map one of those keys to the value, but the exact key
    1181     * which will be mapped is undefined.
    1182     * </p>
    1183     *
    1184     * @param <K> The key type
    1185     * @param <V> The value type
    1186     * @param map The map to invert, must not be null
    1187     * @return A new HashMap containing the inverted data
    1188     * @throws NullPointerException if the map is null
    1189     */
    1190    public static <K, V> Map<V, K> invertMap(final Map<K, V> map) {
    1191        Objects.requireNonNull(map, "map");
    1192        final Map<V, K> out = new HashMap<>(calculateHashMapCapacity(map.size()));
    1193        for (final Entry<K, V> entry : map.entrySet()) {
    1194            out.put(entry.getValue(), entry.getKey());
    1195        }
    1196        return out;
    1197    }
    1198
    1199    /**
    1200     * Null-safe check if the specified map is empty.
    1201     * <p>
    1202     * Null returns true.
    1203     * </p>
    1204     *
    1205     * @param map The map to check, may be null
    1206     * @return true if empty or null
    1207     * @since 3.2
    1208     */
    1209    public static boolean isEmpty(final Map<?, ?> map) {
    1210        return map == null || map.isEmpty();
    1211    }
    1212
    1213    /**
    1214     * Null-safe check if the specified map is not empty.
    1215     * <p>
    1216     * Null returns false.
    1217     * </p>
    1218     *
    1219     * @param map The map to check, may be null
    1220     * @return true if non-null and non-empty
    1221     * @since 3.2
    1222     */
    1223    public static boolean isNotEmpty(final Map<?, ?> map) {
    1224        return !isEmpty(map);
    1225    }
    1226
    1227    /**
    1228     * Gets the specified {@link Map} as an {@link IterableMap}.
    1229     *
    1230     * @param <K> The key type
    1231     * @param <V> The value type
    1232     * @param map to wrap if necessary.
    1233     * @return IterableMap&lt;K, V&gt;
    1234     * @throws NullPointerException if map is null
    1235     * @since 4.0
    1236     */
    1237    public static <K, V> IterableMap<K, V> iterableMap(final Map<K, V> map) {
    1238        Objects.requireNonNull(map, "map");
    1239        return map instanceof IterableMap ? (IterableMap<K, V>) map : new AbstractMapDecorator<K, V>(map) {
    1240            // empty
    1241        };
    1242    }
    1243
    1244    /**
    1245     * Gets the specified {@link SortedMap} as an {@link IterableSortedMap}.
    1246     *
    1247     * @param <K> The key type
    1248     * @param <V> The value type
    1249     * @param sortedMap to wrap if necessary
    1250     * @return {@link IterableSortedMap}&lt;K, V&gt;
    1251     * @throws NullPointerException if sortedMap is null
    1252     * @since 4.0
    1253     */
    1254    public static <K, V> IterableSortedMap<K, V> iterableSortedMap(final SortedMap<K, V> sortedMap) {
    1255        Objects.requireNonNull(sortedMap, "sortedMap");
    1256        return sortedMap instanceof IterableSortedMap ? (IterableSortedMap<K, V>) sortedMap
    1257                : new AbstractSortedMapDecorator<K, V>(sortedMap) {
    1258                    // empty
    1259                };
    1260    }
    1261
    1262    /**
    1263     * Returns a "lazy" map whose values will be created on demand.
    1264     * <p>
    1265     * When the key passed to the returned map's {@link Map#get(Object)} method is not present in the map, then the
    1266     * factory will be used to create a new object and that object will become the value associated with that key.
    1267     * </p>
    1268     * <p>
    1269     * For instance:
    1270     * </p>
    1271     * <pre>
    1272     * Factory factory = new Factory() {
    1273     *     public Object create() {
    1274     *         return new Date();
    1275     *     }
    1276     * }
    1277     * Map lazyMap = MapUtils.lazyMap(new HashMap(), factory);
    1278     * Object obj = lazyMap.get("test");
    1279     * </pre>
    1280     * <p>
    1281     * After the above code is executed, {@code obj} will contain a new {@code Date} instance. Furthermore,
    1282     * that {@code Date} instance is the value for the {@code "test"} key in the map.
    1283     * </p>
    1284     *
    1285     * @param <K> The key type
    1286     * @param <V> The value type
    1287     * @param map The map to make lazy, must not be null
    1288     * @param factory The factory for creating new objects, must not be null
    1289     * @return A lazy map backed by the given map
    1290     * @throws NullPointerException if the Map or Factory is null
    1291     */
    1292    public static <K, V> IterableMap<K, V> lazyMap(final Map<K, V> map, final Factory<? extends V> factory) {
    1293        return LazyMap.lazyMap(map, factory);
    1294    }
    1295
    1296    /**
    1297     * Returns a "lazy" map whose values will be created on demand.
    1298     * <p>
    1299     * When the key passed to the returned map's {@link Map#get(Object)} method is not present in the map, then the
    1300     * factory will be used to create a new object and that object will become the value associated with that key. The
    1301     * factory is a {@link Transformer} that will be passed the key which it must transform into the value.
    1302     * </p>
    1303     * <p>
    1304     * For instance:
    1305     * </p>
    1306     * <pre>
    1307     * Transformer factory = new Transformer() {
    1308     *     public Object transform(Object mapKey) {
    1309     *         return new File(mapKey);
    1310     *     }
    1311     * }
    1312     * Map lazyMap = MapUtils.lazyMap(new HashMap(), factory);
    1313     * Object obj = lazyMap.get("C:/dev");
    1314     * </pre>
    1315     *
    1316     * <p>
    1317     * After the above code is executed, {@code obj} will contain a new {@code File} instance for the C drive
    1318     * dev directory. Furthermore, that {@code File} instance is the value for the {@code "C:/dev"} key in the
    1319     * map.
    1320     * </p>
    1321     * <p>
    1322     * If a lazy map is wrapped by a synchronized map, the result is a simple synchronized cache. When an object is not
    1323     * is the cache, the cache itself calls back to the factory Transformer to populate itself, all within the same
    1324     * synchronized block.
    1325     * </p>
    1326     *
    1327     * @param <K> The key type
    1328     * @param <V> The value type
    1329     * @param map The map to make lazy, must not be null
    1330     * @param transformerFactory The factory for creating new objects, must not be null
    1331     * @return A lazy map backed by the given map
    1332     * @throws NullPointerException if the Map or Transformer is null
    1333     */
    1334    public static <K, V> IterableMap<K, V> lazyMap(final Map<K, V> map,
    1335            final Transformer<? super K, ? extends V> transformerFactory) {
    1336        return LazyMap.lazyMap(map, transformerFactory);
    1337    }
    1338
    1339    /**
    1340     * Returns a "lazy" sorted map whose values will be created on demand.
    1341     * <p>
    1342     * When the key passed to the returned map's {@link Map#get(Object)} method is not present in the map, then the
    1343     * factory will be used to create a new object and that object will become the value associated with that key.
    1344     * </p>
    1345     * <p>
    1346     * For instance:
    1347     * </p>
    1348     * <pre>
    1349     * Factory factory = new Factory() {
    1350     *     public Object create() {
    1351     *         return new Date();
    1352     *     }
    1353     * }
    1354     * SortedMap lazy = MapUtils.lazySortedMap(new TreeMap(), factory);
    1355     * Object obj = lazy.get("test");
    1356     * </pre>
    1357     * <p>
    1358     * After the above code is executed, {@code obj} will contain a new {@code Date} instance. Furthermore,
    1359     * that {@code Date} instance is the value for the {@code "test"} key.
    1360     * </p>
    1361     *
    1362     * @param <K> The key type
    1363     * @param <V> The value type
    1364     * @param map The map to make lazy, must not be null
    1365     * @param factory The factory for creating new objects, must not be null
    1366     * @return A lazy map backed by the given map
    1367     * @throws NullPointerException if the SortedMap or Factory is null
    1368     */
    1369    public static <K, V> SortedMap<K, V> lazySortedMap(final SortedMap<K, V> map, final Factory<? extends V> factory) {
    1370        return LazySortedMap.lazySortedMap(map, factory);
    1371    }
    1372
    1373    /**
    1374     * Returns a "lazy" sorted map whose values will be created on demand.
    1375     * <p>
    1376     * When the key passed to the returned map's {@link Map#get(Object)} method is not present in the map, then the
    1377     * factory will be used to create a new object and that object will become the value associated with that key. The
    1378     * factory is a {@link Transformer} that will be passed the key which it must transform into the value.
    1379     * </p>
    1380     * <p>
    1381     * For instance:
    1382     * </p>
    1383     * <pre>
    1384     * Transformer factory = new Transformer() {
    1385     *     public Object transform(Object mapKey) {
    1386     *         return new File(mapKey);
    1387     *     }
    1388     * }
    1389     * SortedMap lazy = MapUtils.lazySortedMap(new TreeMap(), factory);
    1390     * Object obj = lazy.get("C:/dev");
    1391     * </pre>
    1392     * <p>
    1393     * After the above code is executed, {@code obj} will contain a new {@code File} instance for the C drive
    1394     * dev directory. Furthermore, that {@code File} instance is the value for the {@code "C:/dev"} key in the
    1395     * map.
    1396     * </p>
    1397     * <p>
    1398     * If a lazy map is wrapped by a synchronized map, the result is a simple synchronized cache. When an object is not
    1399     * is the cache, the cache itself calls back to the factory Transformer to populate itself, all within the same
    1400     * synchronized block.
    1401     * </p>
    1402     *
    1403     * @param <K> The key type
    1404     * @param <V> The value type
    1405     * @param map The map to make lazy, must not be null
    1406     * @param transformerFactory The factory for creating new objects, must not be null
    1407     * @return A lazy map backed by the given map
    1408     * @throws NullPointerException if the Map or Transformer is null
    1409     */
    1410    public static <K, V> SortedMap<K, V> lazySortedMap(final SortedMap<K, V> map,
    1411            final Transformer<? super K, ? extends V> transformerFactory) {
    1412        return LazySortedMap.lazySortedMap(map, transformerFactory);
    1413    }
    1414
    1415    /**
    1416     * Creates a multi-value map backed by the given map which returns collections of type ArrayList.
    1417     *
    1418     * @param <K> The key type
    1419     * @param <V> The value type
    1420     * @param map The map to decorate
    1421     * @return A multi-value map backed by the given map which returns ArrayLists of values.
    1422     * @see MultiValueMap
    1423     * @since 3.2
    1424     * @deprecated Since 4.1, use {@link MultiValuedMap} instead
    1425     */
    1426    @Deprecated
    1427    public static <K, V> MultiValueMap<K, V> multiValueMap(final Map<K, ? super Collection<V>> map) {
    1428        return MultiValueMap.<K, V>multiValueMap(map);
    1429    }
    1430
    1431    /**
    1432     * Creates a multi-value map backed by the given map which returns collections of the specified type.
    1433     *
    1434     * @param <K> The key type
    1435     * @param <V> The value type
    1436     * @param <C> The collection class type
    1437     * @param map The map to decorate
    1438     * @param collectionClass The type of collections to return from the map (must contain public no-arg constructor and
    1439     *        extend Collection)
    1440     * @return A multi-value map backed by the given map which returns collections of the specified type
    1441     * @see MultiValueMap
    1442     * @since 3.2
    1443     * @deprecated Since 4.1, use {@link MultiValuedMap} instead
    1444     */
    1445    @Deprecated
    1446    public static <K, V, C extends Collection<V>> MultiValueMap<K, V> multiValueMap(final Map<K, C> map,
    1447            final Class<C> collectionClass) {
    1448        return MultiValueMap.multiValueMap(map, collectionClass);
    1449    }
    1450
    1451    /**
    1452     * Creates a multi-value map backed by the given map which returns collections created by the specified collection
    1453     * factory.
    1454     *
    1455     * @param <K> The key type
    1456     * @param <V> The value type
    1457     * @param <C> The collection class type
    1458     * @param map The map to decorate
    1459     * @param collectionFactory A factor which creates collection objects
    1460     * @return A multi-value map backed by the given map which returns collections created by the specified collection
    1461     *         factory
    1462     * @see MultiValueMap
    1463     * @since 3.2
    1464     * @deprecated Since 4.1, use {@link MultiValuedMap} instead
    1465     */
    1466    @Deprecated
    1467    public static <K, V, C extends Collection<V>> MultiValueMap<K, V> multiValueMap(final Map<K, C> map,
    1468            final Factory<C> collectionFactory) {
    1469        return MultiValueMap.multiValueMap(map, collectionFactory);
    1470    }
    1471
    1472    /**
    1473     * Returns a map that maintains the order of keys that are added backed by the given map.
    1474     * <p>
    1475     * If a key is added twice, the order is determined by the first add. The order is observed through the keySet,
    1476     * values and entrySet.
    1477     * </p>
    1478     *
    1479     * @param <K> The key type
    1480     * @param <V> The value type
    1481     * @param map The map to order, must not be null
    1482     * @return An ordered map backed by the given map
    1483     * @throws NullPointerException if the Map is null
    1484     */
    1485    public static <K, V> OrderedMap<K, V> orderedMap(final Map<K, V> map) {
    1486        return ListOrderedMap.listOrderedMap(map);
    1487    }
    1488
    1489    /**
    1490     * Populates a Map using the supplied {@code Transformer}s to transform the elements into keys and values.
    1491     *
    1492     * @param <K> The key type
    1493     * @param <V> The value type
    1494     * @param <E> The type of object contained in the {@link Iterable}
    1495     * @param map The {@code Map} to populate.
    1496     * @param elements The {@code Iterable} containing the input values for the map.
    1497     * @param keyTransformer The {@code Transformer} used to transform the element into a key value
    1498     * @param valueTransformer The {@code Transformer} used to transform the element into a value
    1499     * @throws NullPointerException if the map, elements or transformers are null
    1500     */
    1501    public static <K, V, E> void populateMap(final Map<K, V> map, final Iterable<? extends E> elements,
    1502            final Transformer<E, K> keyTransformer, final Transformer<E, V> valueTransformer) {
    1503        for (final E temp : elements) {
    1504            map.put(keyTransformer.apply(temp), valueTransformer.apply(temp));
    1505        }
    1506    }
    1507
    1508    /**
    1509     * Populates a Map using the supplied {@code Transformer} to transform the elements into keys, using the
    1510     * unaltered element as the value in the {@code Map}.
    1511     *
    1512     * @param <K> The key type
    1513     * @param <V> The value type
    1514     * @param map The {@code Map} to populate.
    1515     * @param elements The {@code Iterable} containing the input values for the map.
    1516     * @param keyTransformer The {@code Transformer} used to transform the element into a key value
    1517     * @throws NullPointerException if the map, elements or transformer are null
    1518     */
    1519    public static <K, V> void populateMap(final Map<K, V> map, final Iterable<? extends V> elements,
    1520            final Transformer<V, K> keyTransformer) {
    1521        populateMap(map, elements, keyTransformer, TransformerUtils.<V>nopTransformer());
    1522    }
    1523
    1524    /**
    1525     * Populates a MultiMap using the supplied {@code Transformer}s to transform the elements into keys and values.
    1526     *
    1527     * @param <K> The key type
    1528     * @param <V> The value type
    1529     * @param <E> The type of object contained in the {@link Iterable}
    1530     * @param map The {@code MultiMap} to populate.
    1531     * @param elements The {@code Iterable} containing the input values for the map.
    1532     * @param keyTransformer The {@code Transformer} used to transform the element into a key value
    1533     * @param valueTransformer The {@code Transformer} used to transform the element into a value
    1534     * @throws NullPointerException if the map, collection or transformers are null
    1535     */
    1536    public static <K, V, E> void populateMap(final MultiMap<K, V> map, final Iterable<? extends E> elements,
    1537            final Transformer<E, K> keyTransformer, final Transformer<E, V> valueTransformer) {
    1538        for (final E temp : elements) {
    1539            map.put(keyTransformer.apply(temp), valueTransformer.apply(temp));
    1540        }
    1541    }
    1542
    1543    /**
    1544     * Populates a MultiMap using the supplied {@code Transformer} to transform the elements into keys, using the
    1545     * unaltered element as the value in the {@code MultiMap}.
    1546     *
    1547     * @param <K> The key type
    1548     * @param <V> The value type
    1549     * @param map The {@code MultiMap} to populate.
    1550     * @param elements The {@code Iterable} to use as input values for the map.
    1551     * @param keyTransformer The {@code Transformer} used to transform the element into a key value
    1552     * @throws NullPointerException if the map, elements or transformer are null
    1553     */
    1554    public static <K, V> void populateMap(final MultiMap<K, V> map, final Iterable<? extends V> elements,
    1555            final Transformer<V, K> keyTransformer) {
    1556        populateMap(map, elements, keyTransformer, TransformerUtils.<V>nopTransformer());
    1557    }
    1558
    1559    /**
    1560     * Returns a predicated (validating) map backed by the given map.
    1561     * <p>
    1562     * Only objects that pass the tests in the given predicates can be added to the map. Trying to add an invalid object
    1563     * results in an IllegalArgumentException. Keys must pass the key predicate, values must pass the value predicate.
    1564     * It is important not to use the original map after invoking this method, as it is a backdoor for adding invalid
    1565     * objects.
    1566     * </p>
    1567     *
    1568     * @param <K> The key type
    1569     * @param <V> The value type
    1570     * @param map The map to predicate, must not be null
    1571     * @param keyPred The predicate for keys, null means no check
    1572     * @param valuePred The predicate for values, null means no check
    1573     * @return A predicated map backed by the given map
    1574     * @throws NullPointerException if the Map is null
    1575     */
    1576    public static <K, V> IterableMap<K, V> predicatedMap(final Map<K, V> map, final Predicate<? super K> keyPred,
    1577            final Predicate<? super V> valuePred) {
    1578        return PredicatedMap.predicatedMap(map, keyPred, valuePred);
    1579    }
    1580
    1581    /**
    1582     * Returns a predicated (validating) sorted map backed by the given map.
    1583     * <p>
    1584     * Only objects that pass the tests in the given predicates can be added to the map. Trying to add an invalid object
    1585     * results in an IllegalArgumentException. Keys must pass the key predicate, values must pass the value predicate.
    1586     * It is important not to use the original map after invoking this method, as it is a backdoor for adding invalid
    1587     * objects.
    1588     * </p>
    1589     *
    1590     * @param <K> The key type
    1591     * @param <V> The value type
    1592     * @param map The map to predicate, must not be null
    1593     * @param keyPred The predicate for keys, null means no check
    1594     * @param valuePred The predicate for values, null means no check
    1595     * @return A predicated map backed by the given map
    1596     * @throws NullPointerException if the SortedMap is null
    1597     */
    1598    public static <K, V> SortedMap<K, V> predicatedSortedMap(final SortedMap<K, V> map,
    1599            final Predicate<? super K> keyPred, final Predicate<? super V> valuePred) {
    1600        return PredicatedSortedMap.predicatedSortedMap(map, keyPred, valuePred);
    1601    }
    1602
    1603    /**
    1604     * Writes indentation to the given stream.
    1605     *
    1606     * @param out The stream to indent
    1607     * @param indent The index of the indentation
    1608     */
    1609    private static void printIndent(final PrintStream out, final int indent) {
    1610        for (int i = 0; i < indent; i++) {
    1611            out.print(INDENT_STRING);
    1612        }
    1613    }
    1614
    1615    /**
    1616     * Puts all the keys and values from the specified array into the map.
    1617     * <p>
    1618     * This method is an alternative to the {@link Map#putAll(java.util.Map)} method and constructors. It
    1619     * allows you to build a map from an object array of various possible styles.
    1620     * </p>
    1621     * <p>
    1622     * If the first entry in the object array implements {@link Entry} or {@link KeyValue} then the key
    1623     * and value are added from that object. If the first entry in the object array is an object array itself, then it
    1624     * is assumed that index 0 in the sub-array is the key and index 1 is the value. Otherwise, the array is treated as
    1625     * keys and values in alternate indices.
    1626     * </p>
    1627     * <p>
    1628     * For example, to create a color map:
    1629     * </p>
    1630     * <pre>
    1631     * Map colorMap = MapUtils.putAll(new HashMap(),
    1632     *         new String[][] { { "RED", "#FF0000" }, { "GREEN", "#00FF00" }, { "BLUE", "#0000FF" } });
    1633     * </pre>
    1634     * <p>
    1635     * or:
    1636     * </p>
    1637     * <pre>
    1638     * Map colorMap = MapUtils.putAll(new HashMap(),
    1639     *         new String[] { "RED", "#FF0000", "GREEN", "#00FF00", "BLUE", "#0000FF" });
    1640     * </pre>
    1641     * <p>
    1642     * or:
    1643     * </p>
    1644     * <pre>
    1645     * Map colorMap = MapUtils.putAll(new HashMap(), new Map.Entry[] { new DefaultMapEntry("RED", "#FF0000"),
    1646     *         new DefaultMapEntry("GREEN", "#00FF00"), new DefaultMapEntry("BLUE", "#0000FF") });
    1647     * </pre>
    1648     *
    1649     * @param <K> The key type
    1650     * @param <V> The value type
    1651     * @param map The map to populate, must not be null
    1652     * @param array An array to populate from, null ignored
    1653     * @return The input map
    1654     * @throws NullPointerException if map is null
    1655     * @throws IllegalArgumentException if sub-array or entry matching used and an entry is invalid
    1656     * @throws ClassCastException if the array contents is mixed
    1657     * @since 3.2
    1658     */
    1659    @SuppressWarnings("unchecked") // As per Javadoc throws CCE for invalid array contents
    1660    public static <K, V> Map<K, V> putAll(final Map<K, V> map, final Object[] array) {
    1661        Objects.requireNonNull(map, "map");
    1662        if (array == null || array.length == 0) {
    1663            return map;
    1664        }
    1665        final Object obj = array[0];
    1666        if (obj instanceof Map.Entry) {
    1667            for (final Object element : array) {
    1668                // cast ok here, type is checked above
    1669                final Map.Entry<K, V> entry = (Map.Entry<K, V>) element;
    1670                map.put(entry.getKey(), entry.getValue());
    1671            }
    1672        } else if (obj instanceof KeyValue) {
    1673            for (final Object element : array) {
    1674                // cast ok here, type is checked above
    1675                final KeyValue<K, V> keyval = (KeyValue<K, V>) element;
    1676                map.put(keyval.getKey(), keyval.getValue());
    1677            }
    1678        } else if (obj instanceof Object[]) {
    1679            for (int i = 0; i < array.length; i++) {
    1680                final Object[] sub = (Object[]) array[i];
    1681                if (sub == null || sub.length < 2) {
    1682                    throw new IllegalArgumentException("Invalid array element: " + i);
    1683                }
    1684                // these casts can fail if array has incorrect types
    1685                map.put((K) sub[0], (V) sub[1]);
    1686            }
    1687        } else {
    1688            for (int i = 0; i < array.length - 1;) {
    1689                // these casts can fail if array has incorrect types
    1690                map.put((K) array[i++], (V) array[i++]);
    1691            }
    1692        }
    1693        return map;
    1694    }
    1695
    1696    /**
    1697     * Protects against adding null values to a map.
    1698     * <p>
    1699     * This method checks the value being added to the map, and if it is null it is replaced by an empty string.
    1700     * </p>
    1701     * <p>
    1702     * This could be useful if the map does not accept null values, or for receiving data from a source that may provide
    1703     * null or empty string which should be held in the same way in the map.
    1704     * </p>
    1705     * <p>
    1706     * Keys are not validated. Note that this method can be used to circumvent the map's value type at runtime.
    1707     * </p>
    1708     *
    1709     * @param <K> The key type
    1710     * @param map The map to add to, must not be null
    1711     * @param key The key
    1712     * @param value The value, null converted to ""
    1713     * @throws NullPointerException if the map is null
    1714     */
    1715    public static <K> void safeAddToMap(final Map<? super K, Object> map, final K key, final Object value)
    1716            throws NullPointerException {
    1717        Objects.requireNonNull(map, "map");
    1718        map.put(key, value == null ? "" : value);
    1719    }
    1720
    1721    /**
    1722     * Gets the given map size or 0 if the map is null
    1723     *
    1724     * @param map A Map or null
    1725     * @return The given map size or 0 if the map is null
    1726     */
    1727    public static int size(final Map<?, ?> map) {
    1728        return map == null ? 0 : map.size();
    1729    }
    1730
    1731    /**
    1732     * Returns a synchronized map backed by the given map.
    1733     * <p>
    1734     * You must manually synchronize on the returned buffer's iterator to avoid non-deterministic behavior:
    1735     * </p>
    1736     * <pre>
    1737     * Map m = MapUtils.synchronizedMap(myMap);
    1738     * Sets s = m.keySet(); // outside synchronized block
    1739     * synchronized (m) { // synchronized on MAP!
    1740     *     Iterator i = s.iterator();
    1741     *     while (i.hasNext()) {
    1742     *         process(i.next());
    1743     *     }
    1744     * }
    1745     * </pre>
    1746     * <p>
    1747     * This method uses the implementation in {@link Collections Collections}.
    1748     * </p>
    1749     *
    1750     * @param <K> The key type
    1751     * @param <V> The value type
    1752     * @param map The map to synchronize, must not be null
    1753     * @return A synchronized map backed by the given map
    1754     */
    1755    public static <K, V> Map<K, V> synchronizedMap(final Map<K, V> map) {
    1756        return Collections.synchronizedMap(map);
    1757    }
    1758
    1759    /**
    1760     * Returns a synchronized sorted map backed by the given sorted map.
    1761     * <p>
    1762     * You must manually synchronize on the returned buffer's iterator to avoid non-deterministic behavior:
    1763     * </p>
    1764     * <pre>
    1765     * Map m = MapUtils.synchronizedSortedMap(myMap);
    1766     * Sets s = m.keySet(); // outside synchronized block
    1767     * synchronized (m) { // synchronized on MAP!
    1768     *     Iterator i = s.iterator();
    1769     *     while (i.hasNext()) {
    1770     *         process(i.next());
    1771     *     }
    1772     * }
    1773     * </pre>
    1774     * <p>
    1775     * This method uses the implementation in {@link Collections Collections}.
    1776     * </p>
    1777     *
    1778     * @param <K> The key type
    1779     * @param <V> The value type
    1780     * @param map The map to synchronize, must not be null
    1781     * @return A synchronized map backed by the given map
    1782     * @throws NullPointerException if the map is null
    1783     */
    1784    public static <K, V> SortedMap<K, V> synchronizedSortedMap(final SortedMap<K, V> map) {
    1785        return Collections.synchronizedSortedMap(map);
    1786    }
    1787
    1788    /**
    1789     * Creates a new HashMap using data copied from a ResourceBundle.
    1790     *
    1791     * @param resourceBundle The resource bundle to convert, must not be null
    1792     * @return The HashMap containing the data
    1793     * @throws NullPointerException if the bundle is null
    1794     */
    1795    public static Map<String, Object> toMap(final ResourceBundle resourceBundle) {
    1796        Objects.requireNonNull(resourceBundle, "resourceBundle");
    1797        final Enumeration<String> enumeration = resourceBundle.getKeys();
    1798        final Map<String, Object> map = new HashMap<>();
    1799
    1800        while (enumeration.hasMoreElements()) {
    1801            final String key = enumeration.nextElement();
    1802            final Object value = resourceBundle.getObject(key);
    1803            map.put(key, value);
    1804        }
    1805
    1806        return map;
    1807    }
    1808
    1809    /**
    1810     * Gets a new Properties object initialized with the values from a Map. A null input will return an empty properties
    1811     * object.
    1812     * <p>
    1813     * A Properties object may only store non-null keys and values, thus if the provided map contains either a key or
    1814     * value which is {@code null}, a {@link NullPointerException} will be thrown.
    1815     * </p>
    1816     *
    1817     * @param <K> The key type
    1818     * @param <V> The value type
    1819     * @param map The map to convert to a Properties object
    1820     * @return The properties object
    1821     * @throws NullPointerException if a key or value in the provided map is {@code null}
    1822     */
    1823    public static <K, V> Properties toProperties(final Map<K, V> map) {
    1824        final Properties answer = new Properties();
    1825        if (map != null) {
    1826            for (final Entry<K, V> entry2 : map.entrySet()) {
    1827                final Map.Entry<?, ?> entry = entry2;
    1828                final Object key = entry.getKey();
    1829                final Object value = entry.getValue();
    1830                answer.put(key, value);
    1831            }
    1832        }
    1833        return answer;
    1834    }
    1835
    1836    /**
    1837     * Returns a transformed map backed by the given map.
    1838     * <p>
    1839     * This method returns a new map (decorating the specified map) that will transform any new entries added to it.
    1840     * Existing entries in the specified map will not be transformed. If you want that behavior, see
    1841     * {@link TransformedMap#transformedMap}.
    1842     * </p>
    1843     * <p>
    1844     * Each object is passed through the transformers as it is added to the Map. It is important not to use the original
    1845     * map after invoking this method, as it is a backdoor for adding untransformed objects.
    1846     * </p>
    1847     * <p>
    1848     * If there are any elements already in the map being decorated, they are NOT transformed.
    1849     * </p>
    1850     *
    1851     * @param <K> The key type
    1852     * @param <V> The value type
    1853     * @param map The map to transform, must not be null, typically empty
    1854     * @param keyTransformer The transformer for the map keys, null means no transformation
    1855     * @param valueTransformer The transformer for the map values, null means no transformation
    1856     * @return A transformed map backed by the given map
    1857     * @throws NullPointerException if the Map is null
    1858     */
    1859    public static <K, V> IterableMap<K, V> transformedMap(final Map<K, V> map,
    1860            final Transformer<? super K, ? extends K> keyTransformer,
    1861            final Transformer<? super V, ? extends V> valueTransformer) {
    1862        return TransformedMap.transformingMap(map, keyTransformer, valueTransformer);
    1863    }
    1864
    1865    /**
    1866     * Returns a transformed sorted map backed by the given map.
    1867     * <p>
    1868     * This method returns a new sorted map (decorating the specified map) that will transform any new entries added to
    1869     * it. Existing entries in the specified map will not be transformed. If you want that behavior, see
    1870     * {@link TransformedSortedMap#transformedSortedMap}.
    1871     * </p>
    1872     * <p>
    1873     * Each object is passed through the transformers as it is added to the Map. It is important not to use the original
    1874     * map after invoking this method, as it is a backdoor for adding untransformed objects.
    1875     * </p>
    1876     * <p>
    1877     * If there are any elements already in the map being decorated, they are NOT transformed.
    1878     * </p>
    1879     *
    1880     * @param <K> The key type
    1881     * @param <V> The value type
    1882     * @param map The map to transform, must not be null, typically empty
    1883     * @param keyTransformer The transformer for the map keys, null means no transformation
    1884     * @param valueTransformer The transformer for the map values, null means no transformation
    1885     * @return A transformed map backed by the given map
    1886     * @throws NullPointerException if the SortedMap is null
    1887     */
    1888    public static <K, V> SortedMap<K, V> transformedSortedMap(final SortedMap<K, V> map,
    1889            final Transformer<? super K, ? extends K> keyTransformer,
    1890            final Transformer<? super V, ? extends V> valueTransformer) {
    1891        return TransformedSortedMap.transformingSortedMap(map, keyTransformer, valueTransformer);
    1892    }
    1893
    1894    /**
    1895     * Returns an unmodifiable map backed by the given map.
    1896     * <p>
    1897     * This method uses the implementation in the decorators subpackage.
    1898     * </p>
    1899     *
    1900     * @param <K> The key type
    1901     * @param <V> The value type
    1902     * @param map The map to make unmodifiable, must not be null
    1903     * @return An unmodifiable map backed by the given map
    1904     * @throws NullPointerException if the map is null
    1905     */
    1906    public static <K, V> Map<K, V> unmodifiableMap(final Map<? extends K, ? extends V> map) {
    1907        return UnmodifiableMap.unmodifiableMap(map);
    1908    }
    1909
    1910    /**
    1911     * Returns an unmodifiable sorted map backed by the given sorted map.
    1912     * <p>
    1913     * This method uses the implementation in the decorators subpackage.
    1914     * </p>
    1915     *
    1916     * @param <K> The key type
    1917     * @param <V> The value type
    1918     * @param map The sorted map to make unmodifiable, must not be null
    1919     * @return An unmodifiable map backed by the given map
    1920     * @throws NullPointerException if the map is null
    1921     */
    1922    public static <K, V> SortedMap<K, V> unmodifiableSortedMap(final SortedMap<K, ? extends V> map) {
    1923        return UnmodifiableSortedMap.unmodifiableSortedMap(map);
    1924    }
    1925
    1926    /**
    1927     * Prints the given map with nice line breaks.
    1928     * <p>
    1929     * This method prints a nicely formatted String describing the Map. Each map entry will be printed with key and
    1930     * value. When the value is a Map, recursive behavior occurs.
    1931     * </p>
    1932     * <p>
    1933     * This method is NOT thread-safe in any special way. You must manually synchronize on either this class or the
    1934     * stream as required.
    1935     * </p>
    1936     *
    1937     * @param out The stream to print to, must not be null
    1938     * @param label The label to be used, may be {@code null}. If {@code null}, the label is not output. It
    1939     *        typically represents the name of the property in a bean or similar.
    1940     * @param map The map to print, may be {@code null}. If {@code null}, the text 'null' is output.
    1941     * @throws NullPointerException if the stream is {@code null}
    1942     */
    1943    public static void verbosePrint(final PrintStream out, final Object label, final Map<?, ?> map) {
    1944        verbosePrintInternal(out, label, map, new ArrayDeque<>(), false);
    1945    }
    1946
    1947    /**
    1948     * Implementation providing functionality for {@link #debugPrint} and for {@link #verbosePrint}. This prints the
    1949     * given map with nice line breaks. If the debug flag is true, it additionally prints the type of the object value.
    1950     * If the contents of a map include the map itself, then the text <em>(this Map)</em> is printed out. If the
    1951     * contents include a parent container of the map, the text <em>(ancestor[i] Map)</em> is printed, where it actually
    1952     * indicates the number of levels which must be traversed in the sequential list of ancestors (for example father,
    1953     * grandfather, great-grandfather, etc.).
    1954     *
    1955     * @param out The stream to print to
    1956     * @param label The label to be used, may be {@code null}. If {@code null}, the label is not output. It
    1957     *        typically represents the name of the property in a bean or similar.
    1958     * @param map The map to print, may be {@code null}. If {@code null}, the text 'null' is output
    1959     * @param lineage A stack consisting of any maps in which the previous argument is contained. This is checked to
    1960     *        avoid infinite recursion when printing the output
    1961     * @param debug flag indicating whether type names should be output.
    1962     * @throws NullPointerException if the stream is {@code null}
    1963     */
    1964    private static void verbosePrintInternal(final PrintStream out, final Object label, final Map<?, ?> map,
    1965            final Deque<Map<?, ?>> lineage, final boolean debug) {
    1966        printIndent(out, lineage.size());
    1967
    1968        if (map == null) {
    1969            if (label != null) {
    1970                out.print(label);
    1971                out.print(" = ");
    1972            }
    1973            out.println("null");
    1974            return;
    1975        }
    1976        if (label != null) {
    1977            out.print(label);
    1978            out.println(" = ");
    1979        }
    1980
    1981        printIndent(out, lineage.size());
    1982        out.println("{");
    1983
    1984        lineage.addLast(map);
    1985
    1986        for (final Map.Entry<?, ?> entry : map.entrySet()) {
    1987            final Object childKey = entry.getKey();
    1988            final Object childValue = entry.getValue();
    1989            if (childValue instanceof Map && !lineage.contains(childValue)) {
    1990                verbosePrintInternal(out, childKey == null ? "null" : childKey, (Map<?, ?>) childValue, lineage, debug);
    1991            } else {
    1992                printIndent(out, lineage.size());
    1993                out.print(childKey);
    1994                out.print(" = ");
    1995
    1996                final int lineageIndex = IterableUtils.indexOf(lineage, PredicateUtils.equalPredicate(childValue));
    1997                if (lineageIndex == -1) {
    1998                    out.print(childValue);
    1999                } else if (lineage.size() - 1 == lineageIndex) {
    2000                    out.print("(this Map)");
    2001                } else {
    2002                    out.print("(ancestor[" + (lineage.size() - 1 - lineageIndex - 1) + "] Map)");
    2003                }
    2004
    2005                if (debug && childValue != null) {
    2006                    out.print(' ');
    2007                    out.println(childValue.getClass().getName());
    2008                } else {
    2009                    out.println();
    2010                }
    2011            }
    2012        }
    2013
    2014        lineage.removeLast();
    2015
    2016        printIndent(out, lineage.size());
    2017        out.println(debug ? "} " + map.getClass().getName() : "}");
    2018    }
    2019
    2020    /**
    2021     * Don't allow instances.
    2022     */
    2023    private MapUtils() {
    2024    }
    2025
    2026}