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