MapUtils.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.collections4;

  18. import java.io.PrintStream;
  19. import java.text.NumberFormat;
  20. import java.text.ParseException;
  21. import java.util.ArrayDeque;
  22. import java.util.Collection;
  23. import java.util.Collections;
  24. import java.util.Deque;
  25. import java.util.Enumeration;
  26. import java.util.HashMap;
  27. import java.util.Map;
  28. import java.util.Map.Entry;
  29. import java.util.Objects;
  30. import java.util.Properties;
  31. import java.util.ResourceBundle;
  32. import java.util.SortedMap;
  33. import java.util.TreeMap;
  34. import java.util.function.BiFunction;
  35. import java.util.function.Function;

  36. import org.apache.commons.collections4.map.AbstractMapDecorator;
  37. import org.apache.commons.collections4.map.AbstractSortedMapDecorator;
  38. import org.apache.commons.collections4.map.FixedSizeMap;
  39. import org.apache.commons.collections4.map.FixedSizeSortedMap;
  40. import org.apache.commons.collections4.map.LazyMap;
  41. import org.apache.commons.collections4.map.LazySortedMap;
  42. import org.apache.commons.collections4.map.ListOrderedMap;
  43. import org.apache.commons.collections4.map.MultiValueMap;
  44. import org.apache.commons.collections4.map.PredicatedMap;
  45. import org.apache.commons.collections4.map.PredicatedSortedMap;
  46. import org.apache.commons.collections4.map.TransformedMap;
  47. import org.apache.commons.collections4.map.TransformedSortedMap;
  48. import org.apache.commons.collections4.map.UnmodifiableMap;
  49. import org.apache.commons.collections4.map.UnmodifiableSortedMap;

  50. /**
  51.  * Provides utility methods and decorators for {@link Map} and {@link SortedMap} instances.
  52.  * <p>
  53.  * It contains various type safe methods as well as other useful features like deep copying.
  54.  * </p>
  55.  * <p>
  56.  * It also provides the following decorators:
  57.  * </p>
  58.  *
  59.  * <ul>
  60.  * <li>{@link #fixedSizeMap(Map)}
  61.  * <li>{@link #fixedSizeSortedMap(SortedMap)}
  62.  * <li>{@link #lazyMap(Map,Factory)}
  63.  * <li>{@link #lazyMap(Map,Transformer)}
  64.  * <li>{@link #lazySortedMap(SortedMap,Factory)}
  65.  * <li>{@link #lazySortedMap(SortedMap,Transformer)}
  66.  * <li>{@link #predicatedMap(Map,Predicate,Predicate)}
  67.  * <li>{@link #predicatedSortedMap(SortedMap,Predicate,Predicate)}
  68.  * <li>{@link #transformedMap(Map, Transformer, Transformer)}
  69.  * <li>{@link #transformedSortedMap(SortedMap, Transformer, Transformer)}
  70.  * <li>{@link #multiValueMap(Map)}
  71.  * <li>{@link #multiValueMap(Map, Class)}
  72.  * <li>{@link #multiValueMap(Map, Factory)}
  73.  * </ul>
  74.  *
  75.  * @since 1.0
  76.  */
  77. @SuppressWarnings("deprecation")
  78. public class MapUtils {

  79.     /**
  80.      * An empty unmodifiable sorted map. This is not provided in the JDK.
  81.      */
  82.     @SuppressWarnings("rawtypes")
  83.     public static final SortedMap EMPTY_SORTED_MAP = UnmodifiableSortedMap.unmodifiableSortedMap(new TreeMap<>());

  84.     /**
  85.      * String used to indent the verbose and debug Map prints.
  86.      */
  87.     private static final String INDENT_STRING = "    ";

  88.     /**
  89.      * Applies the {@code getFunction} and returns its result if non-null, if null returns the result of applying the
  90.      * default function.
  91.      *
  92.      * @param <K> The key type.
  93.      * @param <R> The result type.
  94.      * @param map The map to query.
  95.      * @param key The key into the map.
  96.      * @param getFunction The get function.
  97.      * @param defaultFunction The function to provide a default value.
  98.      * @return The result of applying a function.
  99.      */
  100.     private static <K, R> R applyDefaultFunction(final Map<? super K, ?> map, final K key,
  101.             final BiFunction<Map<? super K, ?>, K, R> getFunction, final Function<K, R> defaultFunction) {
  102.         return applyDefaultFunction(map, key, getFunction, defaultFunction, null);
  103.     }

  104.     /**
  105.      * Applies the {@code getFunction} and returns its result if non-null, if null returns the result of applying the
  106.      * default function.
  107.      *
  108.      * @param <K> The key type.
  109.      * @param <R> The result type.
  110.      * @param map The map to query.
  111.      * @param key The key into the map.
  112.      * @param getFunction The get function.
  113.      * @param defaultFunction The function to provide a default value.
  114.      * @param defaultValue The default value.
  115.      * @return The result of applying a function.
  116.      */
  117.     private static <K, R> R applyDefaultFunction(final Map<? super K, ?> map, final K key,
  118.             final BiFunction<Map<? super K, ?>, K, R> getFunction, final Function<K, R> defaultFunction,
  119.             final R defaultValue) {
  120.         R value = map != null && getFunction != null ? getFunction.apply(map, key) : null;
  121.         if (value == null) {
  122.             value = defaultFunction != null ? defaultFunction.apply(key) : null;
  123.         }
  124.         return value != null ? value : defaultValue;
  125.     }

  126.     /**
  127.      * Applies the {@code getFunction} and returns its result if non-null, if null returns the {@code defaultValue}.
  128.      *
  129.      * @param <K> The key type.
  130.      * @param <R> The result type.
  131.      * @param map The map to query.
  132.      * @param key The key into the map.
  133.      * @param getFunction The get function.
  134.      * @param defaultValue The default value.
  135.      * @return The result of applying a function.
  136.      */
  137.     private static <K, R> R applyDefaultValue(final Map<? super K, ?> map, final K key,
  138.             final BiFunction<Map<? super K, ?>, K, R> getFunction, final R defaultValue) {
  139.         final R value = map != null && getFunction != null ? getFunction.apply(map, key) : null;
  140.         return value == null ? defaultValue : value;
  141.     }

  142.     /**
  143.      * Prints the given map with nice line breaks.
  144.      * <p>
  145.      * This method prints a nicely formatted String describing the Map. Each map entry will be printed with key, value
  146.      * and value class name. When the value is a Map, recursive behavior occurs.
  147.      * </p>
  148.      * <p>
  149.      * This method is NOT thread-safe in any special way. You must manually synchronize on either this class or the
  150.      * stream as required.
  151.      * </p>
  152.      *
  153.      * @param out the stream to print to, must not be null
  154.      * @param label The label to be used, may be {@code null}. If {@code null}, the label is not output. It
  155.      *        typically represents the name of the property in a bean or similar.
  156.      * @param map The map to print, may be {@code null}. If {@code null}, the text 'null' is output.
  157.      * @throws NullPointerException if the stream is {@code null}
  158.      */
  159.     public static void debugPrint(final PrintStream out, final Object label, final Map<?, ?> map) {
  160.         verbosePrintInternal(out, label, map, new ArrayDeque<>(), true);
  161.     }

  162.     /**
  163.      * Returns an immutable empty map if the argument is {@code null}, or the argument itself otherwise.
  164.      *
  165.      * @param <K> the key type
  166.      * @param <V> the value type
  167.      * @param map the map, possibly {@code null}
  168.      * @return an empty map if the argument is {@code null}
  169.      */
  170.     public static <K, V> Map<K, V> emptyIfNull(final Map<K, V> map) {
  171.         return map == null ? Collections.<K, V>emptyMap() : map;
  172.     }

  173.     /**
  174.      * Returns a fixed-sized map backed by the given map. Elements may not be added or removed from the returned map,
  175.      * but existing elements can be changed (for instance, via the {@link Map#put(Object,Object)} method).
  176.      *
  177.      * @param <K> the key type
  178.      * @param <V> the value type
  179.      * @param map the map whose size to fix, must not be null
  180.      * @return a fixed-size map backed by that map
  181.      * @throws NullPointerException if the Map is null
  182.      */
  183.     public static <K, V> IterableMap<K, V> fixedSizeMap(final Map<K, V> map) {
  184.         return FixedSizeMap.fixedSizeMap(map);
  185.     }

  186.     /**
  187.      * Returns a fixed-sized sorted map backed by the given sorted map. Elements may not be added or removed from the
  188.      * returned map, but existing elements can be changed (for instance, via the {@link Map#put(Object,Object)} method).
  189.      *
  190.      * @param <K> the key type
  191.      * @param <V> the value type
  192.      * @param map the map whose size to fix, must not be null
  193.      * @return a fixed-size map backed by that map
  194.      * @throws NullPointerException if the SortedMap is null
  195.      */
  196.     public static <K, V> SortedMap<K, V> fixedSizeSortedMap(final SortedMap<K, V> map) {
  197.         return FixedSizeSortedMap.fixedSizeSortedMap(map);
  198.     }

  199.     /**
  200.      * Gets a Boolean from a Map in a null-safe manner.
  201.      * <p>
  202.      * If the value is a {@code Boolean} it is returned directly. If the value is a {@code String} and it
  203.      * equals 'true' ignoring case then {@code true} is returned, otherwise {@code false}. If the value is a
  204.      * {@code Number} an integer zero value returns {@code false} and non-zero returns {@code true}.
  205.      * Otherwise, {@code null} is returned.
  206.      * </p>
  207.      *
  208.      * @param <K> the key type
  209.      * @param map the map to use
  210.      * @param key the key to look up
  211.      * @return the value in the Map as a Boolean, {@code null} if null map input
  212.      */
  213.     public static <K> Boolean getBoolean(final Map<? super K, ?> map, final K key) {
  214.         if (map != null) {
  215.             final Object answer = map.get(key);
  216.             if (answer != null) {
  217.                 if (answer instanceof Boolean) {
  218.                     return (Boolean) answer;
  219.                 }
  220.                 if (answer instanceof String) {
  221.                     return Boolean.valueOf((String) answer);
  222.                 }
  223.                 if (answer instanceof Number) {
  224.                     final Number n = (Number) answer;
  225.                     return n.intValue() != 0 ? Boolean.TRUE : Boolean.FALSE;
  226.                 }
  227.             }
  228.         }
  229.         return null;
  230.     }

  231.     /**
  232.      * Looks up the given key in the given map, converting the result into a boolean, using the default value if the
  233.      * conversion fails.
  234.      *
  235.      * @param <K> the key type
  236.      * @param map the map whose value to look up
  237.      * @param key the key of the value to look up in that map
  238.      * @param defaultValue what to return if the value is null or if the conversion fails
  239.      * @return the value in the map as a boolean, or defaultValue if the original value is null, the map is null or the
  240.      *         boolean conversion fails
  241.      */
  242.     public static <K> Boolean getBoolean(final Map<? super K, ?> map, final K key, final Boolean defaultValue) {
  243.         return applyDefaultValue(map, key, MapUtils::getBoolean, defaultValue);
  244.     }

  245.     /**
  246.      * Looks up the given key in the given map, converting the result into a boolean, using the defaultFunction to
  247.      * produce the default value if the 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 defaultFunction what to produce the default value if the value is null or if the conversion fails
  253.      * @return the value in the map as a boolean, or defaultValue produced by the defaultFunction if the original value
  254.      *         is null, the map is null or the boolean conversion fails
  255.      * @since 4.5.0-M1
  256.      */
  257.     public static <K> Boolean getBoolean(final Map<? super K, ?> map, final K key,
  258.             final Function<K, Boolean> defaultFunction) {
  259.         return applyDefaultFunction(map, key, MapUtils::getBoolean, defaultFunction);
  260.     }

  261.     /**
  262.      * Gets a boolean from a Map in a null-safe manner.
  263.      * <p>
  264.      * If the value is a {@code Boolean} its value is returned. If the value is a {@code String} and it equals
  265.      * 'true' ignoring case then {@code true} is returned, otherwise {@code false}. If the value is a
  266.      * {@code Number} an integer zero value returns {@code false} and non-zero returns {@code true}.
  267.      * Otherwise, {@code false} is returned.
  268.      * </p>
  269.      *
  270.      * @param <K> the key type
  271.      * @param map the map to use
  272.      * @param key the key to look up
  273.      * @return the value in the Map as a Boolean, {@code false} if null map input
  274.      */
  275.     public static <K> boolean getBooleanValue(final Map<? super K, ?> map, final K key) {
  276.         return Boolean.TRUE.equals(getBoolean(map, key));
  277.     }

  278.     /**
  279.      * Gets a boolean from a Map in a null-safe manner, using the default value if the conversion fails.
  280.      * <p>
  281.      * If the value is a {@code Boolean} its value is returned. If the value is a {@code String} and it equals
  282.      * 'true' ignoring case then {@code true} is returned, otherwise {@code false}. If the value is a
  283.      * {@code Number} an integer zero value returns {@code false} and non-zero returns {@code true}.
  284.      * Otherwise, {@code defaultValue} is returned.
  285.      * </p>
  286.      *
  287.      * @param <K> the key type
  288.      * @param map the map to use
  289.      * @param key the key to look up
  290.      * @param defaultValue return if the value is null or if the conversion fails
  291.      * @return the value in the Map as a Boolean, {@code defaultValue} if null map input
  292.      */
  293.     public static <K> boolean getBooleanValue(final Map<? super K, ?> map, final K key, final boolean defaultValue) {
  294.         return applyDefaultValue(map, key, MapUtils::getBoolean, defaultValue).booleanValue();
  295.     }

  296.     /**
  297.      * Gets a boolean from a Map in a null-safe manner, using the default value produced by the defaultFunction if the
  298.      * conversion fails.
  299.      * <p>
  300.      * If the value is a {@code Boolean} its value is returned. If the value is a {@code String} and it equals
  301.      * 'true' ignoring case then {@code true} is returned, otherwise {@code false}. If the value is a
  302.      * {@code Number} an integer zero value returns {@code false} and non-zero returns {@code true}.
  303.      * Otherwise, defaultValue produced by the {@code defaultFunction} is returned.
  304.      * </p>
  305.      *
  306.      * @param <K> the key type
  307.      * @param map the map to use
  308.      * @param key the key to look up
  309.      * @param defaultFunction produce the default value to return if the value is null or if the conversion fails
  310.      * @return the value in the Map as a Boolean, default value produced by the {@code defaultFunction} if null map
  311.      *         input
  312.      * @since 4.5.0-M1
  313.      */
  314.     public static <K> boolean getBooleanValue(final Map<? super K, ?> map, final K key,
  315.             final Function<K, Boolean> defaultFunction) {
  316.         return applyDefaultFunction(map, key, MapUtils::getBoolean, defaultFunction, false).booleanValue();
  317.     }

  318.     /**
  319.      * Gets a Byte from a Map in a null-safe manner.
  320.      * <p>
  321.      * The Byte is obtained from the results of {@link #getNumber(Map,Object)}.
  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.      * @return the value in the Map as a Byte, {@code null} if null map input
  328.      */
  329.     public static <K> Byte getByte(final Map<? super K, ?> map, final K key) {
  330.         final Number answer = getNumber(map, key);
  331.         if (answer == null) {
  332.             return null;
  333.         }
  334.         if (answer instanceof Byte) {
  335.             return (Byte) answer;
  336.         }
  337.         return Byte.valueOf(answer.byteValue());
  338.     }

  339.     /**
  340.      * Looks up the given key in the given map, converting the result into a byte, using the default value if the
  341.      * conversion fails.
  342.      *
  343.      * @param <K> the key type
  344.      * @param map the map whose value to look up
  345.      * @param key the key of the value to look up in that map
  346.      * @param defaultValue what to return if the value is null or if the conversion fails
  347.      * @return the value in the map as a number, or defaultValue if the original value is null, the map is null or the
  348.      *         number conversion fails
  349.      */
  350.     public static <K> Byte getByte(final Map<? super K, ?> map, final K key, final Byte defaultValue) {
  351.         return applyDefaultValue(map, key, MapUtils::getByte, defaultValue);
  352.     }

  353.     /**
  354.      * Looks up the given key in the given map, converting the result into a byte, using the defaultFunction to produce
  355.      * the default value if the conversion fails.
  356.      *
  357.      * @param <K> the key type
  358.      * @param map the map whose value to look up
  359.      * @param key the key of the value to look up in that map
  360.      * @param defaultFunction what to produce the default value if the value is null or if the conversion fails
  361.      * @return the value in the map as a number, or defaultValue produced by the defaultFunction if the original value
  362.      *         is null, the map is null or the number conversion fails
  363.      * @since 4.5.0-M1
  364.      */
  365.     public static <K> Byte getByte(final Map<? super K, ?> map, final K key, final Function<K, Byte> defaultFunction) {
  366.         return applyDefaultFunction(map, key, MapUtils::getByte, defaultFunction);
  367.     }

  368.     /**
  369.      * Gets a byte from a Map in a null-safe manner.
  370.      * <p>
  371.      * The byte is obtained from the results of {@link #getNumber(Map,Object)}.
  372.      * </p>
  373.      *
  374.      * @param <K> the key type
  375.      * @param map the map to use
  376.      * @param key the key to look up
  377.      * @return the value in the Map as a byte, {@code 0} if null map input
  378.      */
  379.     public static <K> byte getByteValue(final Map<? super K, ?> map, final K key) {
  380.         return applyDefaultValue(map, key, MapUtils::getByte, 0).byteValue();
  381.     }

  382.     /**
  383.      * Gets a byte from a Map in a null-safe manner, using the default value if the conversion fails.
  384.      * <p>
  385.      * The byte is obtained from the results of {@link #getNumber(Map,Object)}.
  386.      * </p>
  387.      *
  388.      * @param <K> the key type
  389.      * @param map the map to use
  390.      * @param key the key to look up
  391.      * @param defaultValue return if the value is null or if the conversion fails
  392.      * @return the value in the Map as a byte, {@code defaultValue} if null map input
  393.      */
  394.     public static <K> byte getByteValue(final Map<? super K, ?> map, final K key, final byte defaultValue) {
  395.         return applyDefaultValue(map, key, MapUtils::getByte, defaultValue).byteValue();
  396.     }

  397.     /**
  398.      * Gets a byte from a Map in a null-safe manner, using the default value produced by the defaultFunction if the
  399.      * conversion fails.
  400.      * <p>
  401.      * The byte is obtained from the results of {@link #getNumber(Map,Object)}.
  402.      * </p>
  403.      *
  404.      * @param <K> the key type
  405.      * @param map the map to use
  406.      * @param key the key to look up
  407.      * @param defaultFunction produce the default value to return if the value is null or if the conversion fails
  408.      * @return the value in the Map as a byte, default value produced by the {@code defaultFunction} if null map
  409.      *         input
  410.      * @since 4.5.0-M1
  411.      */
  412.     public static <K> byte getByteValue(final Map<? super K, ?> map, final K key,
  413.             final Function<K, Byte> defaultFunction) {
  414.         return applyDefaultFunction(map, key, MapUtils::getByte, defaultFunction, (byte) 0).byteValue();
  415.     }

  416.     /**
  417.      * Gets a Double from a Map in a null-safe manner.
  418.      * <p>
  419.      * The Double is obtained from the results of {@link #getNumber(Map,Object)}.
  420.      * </p>
  421.      *
  422.      * @param <K> the key type
  423.      * @param map the map to use
  424.      * @param key the key to look up
  425.      * @return the value in the Map as a Double, {@code null} if null map input
  426.      */
  427.     public static <K> Double getDouble(final Map<? super K, ?> map, final K key) {
  428.         final Number answer = getNumber(map, key);
  429.         if (answer == null) {
  430.             return null;
  431.         }
  432.         if (answer instanceof Double) {
  433.             return (Double) answer;
  434.         }
  435.         return Double.valueOf(answer.doubleValue());
  436.     }

  437.     /**
  438.      * Looks up the given key in the given map, converting the result into a double, using the default value if the
  439.      * conversion fails.
  440.      *
  441.      * @param <K> the key type
  442.      * @param map the map whose value to look up
  443.      * @param key the key of the value to look up in that map
  444.      * @param defaultValue what to return if the value is null or if the conversion fails
  445.      * @return the value in the map as a number, or defaultValue if the original value is null, the map is null or the
  446.      *         number conversion fails
  447.      */
  448.     public static <K> Double getDouble(final Map<? super K, ?> map, final K key, final Double defaultValue) {
  449.         return applyDefaultValue(map, key, MapUtils::getDouble, defaultValue);
  450.     }

  451.     /**
  452.      * Looks up the given key in the given map, converting the result into a double, using the defaultFunction to
  453.      * produce the default value if the conversion fails.
  454.      *
  455.      * @param <K> the key type
  456.      * @param map the map whose value to look up
  457.      * @param key the key of the value to look up in that map
  458.      * @param defaultFunction what to produce the default value if the value is null or if the conversion fails
  459.      * @return the value in the map as a number, or defaultValue produced by the defaultFunction if the original value
  460.      *         is null, the map is null or the number conversion fails
  461.      * @since 4.5.0-M1
  462.      */
  463.     public static <K> Double getDouble(final Map<? super K, ?> map, final K key,
  464.             final Function<K, Double> defaultFunction) {
  465.         return applyDefaultFunction(map, key, MapUtils::getDouble, defaultFunction);
  466.     }

  467.     /**
  468.      * Gets a double from a Map in a null-safe manner.
  469.      * <p>
  470.      * The double is obtained from the results of {@link #getNumber(Map,Object)}.
  471.      * </p>
  472.      *
  473.      * @param <K> the key type
  474.      * @param map the map to use
  475.      * @param key the key to look up
  476.      * @return the value in the Map as a double, {@code 0.0} if null map input
  477.      */
  478.     public static <K> double getDoubleValue(final Map<? super K, ?> map, final K key) {
  479.         return applyDefaultValue(map, key, MapUtils::getDouble, 0d).doubleValue();
  480.     }

  481.     /**
  482.      * Gets a double from a Map in a null-safe manner, using the default value if the conversion fails.
  483.      * <p>
  484.      * The double is obtained from the results of {@link #getNumber(Map,Object)}.
  485.      * </p>
  486.      *
  487.      * @param <K> the key type
  488.      * @param map the map to use
  489.      * @param key the key to look up
  490.      * @param defaultValue return if the value is null or if the conversion fails
  491.      * @return the value in the Map as a double, {@code defaultValue} if null map input
  492.      */
  493.     public static <K> double getDoubleValue(final Map<? super K, ?> map, final K key, final double defaultValue) {
  494.         return applyDefaultValue(map, key, MapUtils::getDouble, defaultValue).doubleValue();
  495.     }

  496.     /**
  497.      * Gets a double from a Map in a null-safe manner, using the default value produced by the defaultFunction if the
  498.      * conversion fails.
  499.      * <p>
  500.      * The double is obtained from the results of {@link #getNumber(Map,Object)}.
  501.      * </p>
  502.      *
  503.      * @param <K> the key type
  504.      * @param map the map to use
  505.      * @param key the key to look up
  506.      * @param defaultFunction produce the default value to return if the value is null or if the conversion fails
  507.      * @return the value in the Map as a double, default value produced by the {@code defaultFunction} if null map
  508.      *         input
  509.      * @since 4.5.0-M1
  510.      */
  511.     public static <K> double getDoubleValue(final Map<? super K, ?> map, final K key,
  512.             final Function<K, Double> defaultFunction) {
  513.         return applyDefaultFunction(map, key, MapUtils::getDouble, defaultFunction, 0d).doubleValue();
  514.     }

  515.     /**
  516.      * Gets a Float from a Map in a null-safe manner.
  517.      * <p>
  518.      * The Float is obtained from the results of {@link #getNumber(Map,Object)}.
  519.      * </p>
  520.      *
  521.      * @param <K> the key type
  522.      * @param map the map to use
  523.      * @param key the key to look up
  524.      * @return the value in the Map as a Float, {@code null} if null map input
  525.      */
  526.     public static <K> Float getFloat(final Map<? super K, ?> map, final K key) {
  527.         final Number answer = getNumber(map, key);
  528.         if (answer == null) {
  529.             return null;
  530.         }
  531.         if (answer instanceof Float) {
  532.             return (Float) answer;
  533.         }
  534.         return Float.valueOf(answer.floatValue());
  535.     }

  536.     /**
  537.      * Looks up the given key in the given map, converting the result into a float, using the default value if the
  538.      * conversion fails.
  539.      *
  540.      * @param <K> the key type
  541.      * @param map the map whose value to look up
  542.      * @param key the key of the value to look up in that map
  543.      * @param defaultValue what to return if the value is null or if the conversion fails
  544.      * @return the value in the map as a number, or defaultValue if the original value is null, the map is null or the
  545.      *         number conversion fails
  546.      */
  547.     public static <K> Float getFloat(final Map<? super K, ?> map, final K key, final Float defaultValue) {
  548.         return applyDefaultValue(map, key, MapUtils::getFloat, defaultValue);
  549.     }

  550.     /**
  551.      * Looks up the given key in the given map, converting the result into a float, using the defaultFunction to produce
  552.      * the default value if the conversion fails.
  553.      *
  554.      * @param <K> the key type
  555.      * @param map the map whose value to look up
  556.      * @param key the key of the value to look up in that map
  557.      * @param defaultFunction what to produce the default value if the value is null or if the conversion fails
  558.      * @return the value in the map as a number, or defaultValue produced by the defaultFunction if the original value
  559.      *         is null, the map is null or the number conversion fails
  560.      * @since 4.5.0-M1
  561.      */
  562.     public static <K> Float getFloat(final Map<? super K, ?> map, final K key,
  563.             final Function<K, Float> defaultFunction) {
  564.         return applyDefaultFunction(map, key, MapUtils::getFloat, defaultFunction);
  565.     }

  566.     /**
  567.      * Gets a float from a Map in a null-safe manner.
  568.      * <p>
  569.      * The float is obtained from the results of {@link #getNumber(Map,Object)}.
  570.      * </p>
  571.      *
  572.      * @param <K> the key type
  573.      * @param map the map to use
  574.      * @param key the key to look up
  575.      * @return the value in the Map as a float, {@code 0.0F} if null map input
  576.      */
  577.     public static <K> float getFloatValue(final Map<? super K, ?> map, final K key) {
  578.         return applyDefaultValue(map, key, MapUtils::getFloat, 0f).floatValue();
  579.     }

  580.     /**
  581.      * Gets a float from a Map in a null-safe manner, using the default value if the conversion fails.
  582.      * <p>
  583.      * The float is obtained from the results of {@link #getNumber(Map,Object)}.
  584.      * </p>
  585.      *
  586.      * @param <K> the key type
  587.      * @param map the map to use
  588.      * @param key the key to look up
  589.      * @param defaultValue return if the value is null or if the conversion fails
  590.      * @return the value in the Map as a float, {@code defaultValue} if null map input
  591.      */
  592.     public static <K> float getFloatValue(final Map<? super K, ?> map, final K key, final float defaultValue) {
  593.         return applyDefaultValue(map, key, MapUtils::getFloat, defaultValue).floatValue();
  594.     }

  595.     /**
  596.      * Gets a float from a Map in a null-safe manner, using the default value produced by the defaultFunction if the
  597.      * conversion fails.
  598.      * <p>
  599.      * The float is obtained from the results of {@link #getNumber(Map,Object)}.
  600.      * </p>
  601.      *
  602.      * @param <K> the key type
  603.      * @param map the map to use
  604.      * @param key the key to look up
  605.      * @param defaultFunction produce the default value to return if the value is null or if the conversion fails
  606.      * @return the value in the Map as a float, default value produced by the {@code defaultFunction} if null map
  607.      *         input
  608.      * @since 4.5.0-M1
  609.      */
  610.     public static <K> float getFloatValue(final Map<? super K, ?> map, final K key,
  611.             final Function<K, Float> defaultFunction) {
  612.         return applyDefaultFunction(map, key, MapUtils::getFloat, defaultFunction, 0f).floatValue();
  613.     }

  614.     /**
  615.      * Gets an Integer from a Map in a null-safe manner.
  616.      * <p>
  617.      * The Integer is obtained from the results of {@link #getNumber(Map,Object)}.
  618.      * </p>
  619.      *
  620.      * @param <K> the key type
  621.      * @param map the map to use
  622.      * @param key the key to look up
  623.      * @return the value in the Map as an Integer, {@code null} if null map input
  624.      */
  625.     public static <K> Integer getInteger(final Map<? super K, ?> map, final K key) {
  626.         final Number answer = getNumber(map, key);
  627.         if (answer == null) {
  628.             return null;
  629.         }
  630.         if (answer instanceof Integer) {
  631.             return (Integer) answer;
  632.         }
  633.         return Integer.valueOf(answer.intValue());
  634.     }

  635.     /**
  636.      * Looks up the given key in the given map, converting the result into an integer, using the defaultFunction to
  637.      * produce the default value if the conversion fails.
  638.      *
  639.      * @param <K> the key type
  640.      * @param map the map whose value to look up
  641.      * @param key the key of the value to look up in that map
  642.      * @param defaultFunction what to produce the default value if the value is null or if the conversion fails
  643.      * @return the value in the map as a number, or defaultValue produced by the defaultFunction if the original value
  644.      *         is null, the map is null or the number conversion fails
  645.      * @since 4.5.0-M1
  646.      */
  647.     public static <K> Integer getInteger(final Map<? super K, ?> map, final K key,
  648.             final Function<K, Integer> defaultFunction) {
  649.         return applyDefaultFunction(map, key, MapUtils::getInteger, defaultFunction);
  650.     }

  651.     /**
  652.      * Looks up the given key in the given map, converting the result into an integer, using the default value if the
  653.      * conversion fails.
  654.      *
  655.      * @param <K> the key type
  656.      * @param map the map whose value to look up
  657.      * @param key the key of the value to look up in that map
  658.      * @param defaultValue what to return if the value is null or if the conversion fails
  659.      * @return the value in the map as a number, or defaultValue if the original value is null, the map is null or the
  660.      *         number conversion fails
  661.      */
  662.     public static <K> Integer getInteger(final Map<? super K, ?> map, final K key, final Integer defaultValue) {
  663.         return applyDefaultValue(map, key, MapUtils::getInteger, defaultValue);
  664.     }

  665.     /**
  666.      * Gets an int from a Map in a null-safe manner.
  667.      * <p>
  668.      * The int is obtained from the results of {@link #getNumber(Map,Object)}.
  669.      * </p>
  670.      *
  671.      * @param <K> the key type
  672.      * @param map the map to use
  673.      * @param key the key to look up
  674.      * @return the value in the Map as an int, {@code 0} if null map input
  675.      */
  676.     public static <K> int getIntValue(final Map<? super K, ?> map, final K key) {
  677.         return applyDefaultValue(map, key, MapUtils::getInteger, 0).intValue();
  678.     }

  679.     /**
  680.      * Gets an int from a Map in a null-safe manner, using the default value produced by the defaultFunction if the
  681.      * conversion fails.
  682.      * <p>
  683.      * The int is obtained from the results of {@link #getNumber(Map,Object)}.
  684.      * </p>
  685.      *
  686.      * @param <K> the key type
  687.      * @param map the map to use
  688.      * @param key the key to look up
  689.      * @param defaultFunction produce the default value to return if the value is null or if the conversion fails
  690.      * @return the value in the Map as an int, default value produced by the {@code defaultFunction} if null map
  691.      *         input
  692.      * @since 4.5.0-M1
  693.      */
  694.     public static <K> int getIntValue(final Map<? super K, ?> map, final K key,
  695.             final Function<K, Integer> defaultFunction) {
  696.         return applyDefaultFunction(map, key, MapUtils::getInteger, defaultFunction, 0).byteValue();
  697.     }

  698.     /**
  699.      * Gets an int from a Map in a null-safe manner, using the default value if the conversion fails.
  700.      * <p>
  701.      * The int is obtained from the results of {@link #getNumber(Map,Object)}.
  702.      * </p>
  703.      *
  704.      * @param <K> the key type
  705.      * @param map the map to use
  706.      * @param key the key to look up
  707.      * @param defaultValue return if the value is null or if the conversion fails
  708.      * @return the value in the Map as an int, {@code defaultValue} if null map input
  709.      */
  710.     public static <K> int getIntValue(final Map<? super K, ?> map, final K key, final int defaultValue) {
  711.         return applyDefaultValue(map, key, MapUtils::getInteger, defaultValue).intValue();
  712.     }

  713.     /**
  714.      * Gets a Long from a Map in a null-safe manner.
  715.      * <p>
  716.      * The Long is obtained from the results of {@link #getNumber(Map,Object)}.
  717.      * </p>
  718.      *
  719.      * @param <K> the key type
  720.      * @param map the map to use
  721.      * @param key the key to look up
  722.      * @return the value in the Map as a Long, {@code null} if null map input
  723.      */
  724.     public static <K> Long getLong(final Map<? super K, ?> map, final K key) {
  725.         final Number answer = getNumber(map, key);
  726.         if (answer == null) {
  727.             return null;
  728.         }
  729.         if (answer instanceof Long) {
  730.             return (Long) answer;
  731.         }
  732.         return Long.valueOf(answer.longValue());
  733.     }

  734.     /**
  735.      * Looks up the given key in the given map, converting the result into a Long, using the defaultFunction to produce
  736.      * the default value if the conversion fails.
  737.      *
  738.      * @param <K> the key type
  739.      * @param map the map whose value to look up
  740.      * @param key the key of the value to look up in that map
  741.      * @param defaultFunction what to produce the default value if the value is null or if the conversion fails
  742.      * @return the value in the map as a number, or defaultValue produced by the defaultFunction if the original value
  743.      *         is null, the map is null or the number conversion fails
  744.      * @since 4.5.0-M1
  745.      */
  746.     public static <K> Long getLong(final Map<? super K, ?> map, final K key, final Function<K, Long> defaultFunction) {
  747.         return applyDefaultFunction(map, key, MapUtils::getLong, defaultFunction);
  748.     }

  749.     /**
  750.      * Looks up the given key in the given map, converting the result into a long, using the default value if the
  751.      * conversion fails.
  752.      *
  753.      * @param <K> the key type
  754.      * @param map the map whose value to look up
  755.      * @param key the key of the value to look up in that map
  756.      * @param defaultValue what to return if the value is null or if the conversion fails
  757.      * @return the value in the map as a number, or defaultValue if the original value is null, the map is null or the
  758.      *         number conversion fails
  759.      */
  760.     public static <K> Long getLong(final Map<? super K, ?> map, final K key, final Long defaultValue) {
  761.         return applyDefaultValue(map, key, MapUtils::getLong, defaultValue);
  762.     }

  763.     /**
  764.      * Gets a long from a Map in a null-safe manner.
  765.      * <p>
  766.      * The long is obtained from the results of {@link #getNumber(Map,Object)}.
  767.      * </p>
  768.      *
  769.      * @param <K> the key type
  770.      * @param map the map to use
  771.      * @param key the key to look up
  772.      * @return the value in the Map as a long, {@code 0L} if null map input
  773.      */
  774.     public static <K> long getLongValue(final Map<? super K, ?> map, final K key) {
  775.         return applyDefaultValue(map, key, MapUtils::getLong, 0L).longValue();
  776.     }

  777.     /**
  778.      * Gets a long from a Map in a null-safe manner, using the default value produced by the defaultFunction if the
  779.      * conversion fails.
  780.      * <p>
  781.      * The long is obtained from the results of {@link #getNumber(Map,Object)}.
  782.      * </p>
  783.      *
  784.      * @param <K> the key type
  785.      * @param map the map to use
  786.      * @param key the key to look up
  787.      * @param defaultFunction produce the default value to return if the value is null or if the conversion fails
  788.      * @return the value in the Map as a long, default value produced by the {@code defaultFunction} if null map
  789.      *         input
  790.      * @since 4.5.0-M1
  791.      */
  792.     public static <K> long getLongValue(final Map<? super K, ?> map, final K key,
  793.             final Function<K, Long> defaultFunction) {
  794.         return applyDefaultFunction(map, key, MapUtils::getLong, defaultFunction, 0L).byteValue();
  795.     }

  796.     /**
  797.      * Gets a long from a Map in a null-safe manner, using the default value if the conversion fails.
  798.      * <p>
  799.      * The long is obtained from the results of {@link #getNumber(Map,Object)}.
  800.      * </p>
  801.      *
  802.      * @param <K> the key type
  803.      * @param map the map to use
  804.      * @param key the key to look up
  805.      * @param defaultValue return if the value is null or if the conversion fails
  806.      * @return the value in the Map as a long, {@code defaultValue} if null map input
  807.      */
  808.     public static <K> long getLongValue(final Map<? super K, ?> map, final K key, final long defaultValue) {
  809.         return applyDefaultValue(map, key, MapUtils::getLong, defaultValue).longValue();
  810.     }

  811.     /**
  812.      * Gets a Map from a Map in a null-safe manner.
  813.      * <p>
  814.      * If the value returned from the specified map is not a Map then {@code null} is returned.
  815.      * </p>
  816.      *
  817.      * @param <K> the key type
  818.      * @param map the map to use
  819.      * @param key the key to look up
  820.      * @return the value in the Map as a Map, {@code null} if null map input
  821.      */
  822.     public static <K> Map<?, ?> getMap(final Map<? super K, ?> map, final K key) {
  823.         if (map != null) {
  824.             final Object answer = map.get(key);
  825.             if (answer instanceof Map) {
  826.                 return (Map<?, ?>) answer;
  827.             }
  828.         }
  829.         return null;
  830.     }

  831.     /**
  832.      * Looks up the given key in the given map, converting the result into a map, using the defaultFunction to produce
  833.      * the default value if the conversion fails.
  834.      *
  835.      * @param <K> the key type
  836.      * @param map the map whose value to look up
  837.      * @param key the key of the value to look up in that map
  838.      * @param defaultFunction what to produce the default value if the value is null or if the conversion fails
  839.      * @return the value in the map as a number, or defaultValue produced by the defaultFunction if the original value
  840.      *         is null, the map is null or the map conversion fails
  841.      * @since 4.5.0-M1
  842.      */
  843.     public static <K> Map<?, ?> getMap(final Map<? super K, ?> map, final K key,
  844.             final Function<K, Map<?, ?>> defaultFunction) {
  845.         return applyDefaultFunction(map, key, MapUtils::getMap, defaultFunction);
  846.     }

  847.     /**
  848.      * Looks up the given key in the given map, converting the result into a map, using the default value if the
  849.      * conversion fails.
  850.      *
  851.      * @param <K> the key type
  852.      * @param map the map whose value to look up
  853.      * @param key the key of the value to look up in that map
  854.      * @param defaultValue what to return if the value is null or if the conversion fails
  855.      * @return the value in the map as a number, or defaultValue if the original value is null, the map is null or the
  856.      *         map conversion fails
  857.      */
  858.     public static <K> Map<?, ?> getMap(final Map<? super K, ?> map, final K key, final Map<?, ?> defaultValue) {
  859.         return applyDefaultValue(map, key, MapUtils::getMap, defaultValue);
  860.     }

  861.     /**
  862.      * Gets a Number from a Map in a null-safe manner.
  863.      * <p>
  864.      * If the value is a {@code Number} it is returned directly. If the value is a {@code String} it is
  865.      * converted using {@link NumberFormat#parse(String)} on the system default formatter returning {@code null} if
  866.      * the conversion fails. Otherwise, {@code null} is returned.
  867.      * </p>
  868.      *
  869.      * @param <K> the key type
  870.      * @param map the map to use
  871.      * @param key the key to look up
  872.      * @return the value in the Map as a Number, {@code null} if null map input
  873.      */
  874.     public static <K> Number getNumber(final Map<? super K, ?> map, final K key) {
  875.         if (map != null) {
  876.             final Object answer = map.get(key);
  877.             if (answer != null) {
  878.                 if (answer instanceof Number) {
  879.                     return (Number) answer;
  880.                 }
  881.                 if (answer instanceof String) {
  882.                     try {
  883.                         final String text = (String) answer;
  884.                         return NumberFormat.getInstance().parse(text);
  885.                     } catch (final ParseException e) { // NOPMD
  886.                         // failure means null is returned
  887.                     }
  888.                 }
  889.             }
  890.         }
  891.         return null;
  892.     }

  893.     /**
  894.      * Looks up the given key in the given map, converting the result into a number, using the defaultFunction to
  895.      * produce the default value if the conversion fails.
  896.      *
  897.      * @param <K> the key type
  898.      * @param map the map whose value to look up
  899.      * @param key the key of the value to look up in that map
  900.      * @param defaultFunction what to produce the default value if the value is null or if the conversion fails
  901.      * @return the value in the map as a number, or defaultValue produced by the defaultFunction if the original value
  902.      *         is null, the map is null or the number conversion fails
  903.      * @since 4.5.0-M1
  904.      */
  905.     public static <K> Number getNumber(final Map<? super K, ?> map, final K key,
  906.             final Function<K, Number> defaultFunction) {
  907.         return applyDefaultFunction(map, key, MapUtils::getNumber, defaultFunction);
  908.     }

  909.     /**
  910.      * Looks up the given key in the given map, converting the result into a number, using the default value if the
  911.      * conversion fails.
  912.      *
  913.      * @param <K> the key type
  914.      * @param map the map whose value to look up
  915.      * @param key the key of the value to look up in that map
  916.      * @param defaultValue what to return if the value is null or if the conversion fails
  917.      * @return the value in the map as a number, or defaultValue if the original value is null, the map is null or the
  918.      *         number conversion fails
  919.      */
  920.     public static <K> Number getNumber(final Map<? super K, ?> map, final K key, final Number defaultValue) {
  921.         return applyDefaultValue(map, key, MapUtils::getNumber, defaultValue);
  922.     }

  923.     /**
  924.      * Gets from a Map in a null-safe manner.
  925.      *
  926.      * @param <K> the key type
  927.      * @param <V> the value type
  928.      * @param map the map to use
  929.      * @param key the key to look up
  930.      * @return the value in the Map, {@code null} if null map input
  931.      */
  932.     public static <K, V> V getObject(final Map<? super K, V> map, final K key) {
  933.         if (map != null) {
  934.             return map.get(key);
  935.         }
  936.         return null;
  937.     }

  938.     /**
  939.      * Looks up the given key in the given map, converting null into the given default value.
  940.      *
  941.      * @param <K> the key type
  942.      * @param <V> the value type
  943.      * @param map the map whose value to look up
  944.      * @param key the key of the value to look up in that map
  945.      * @param defaultValue what to return if the value is null
  946.      * @return the value in the map, or defaultValue if the original value is null or the map is null
  947.      */
  948.     public static <K, V> V getObject(final Map<K, V> map, final K key, final V defaultValue) {
  949.         if (map != null) {
  950.             final V answer = map.get(key);
  951.             if (answer != null) {
  952.                 return answer;
  953.             }
  954.         }
  955.         return defaultValue;
  956.     }

  957.     /**
  958.      * Gets a Short from a Map in a null-safe manner.
  959.      * <p>
  960.      * The Short is obtained from the results of {@link #getNumber(Map,Object)}.
  961.      * </p>
  962.      *
  963.      * @param <K> the key type
  964.      * @param map the map to use
  965.      * @param key the key to look up
  966.      * @return the value in the Map as a Short, {@code null} if null map input
  967.      */
  968.     public static <K> Short getShort(final Map<? super K, ?> map, final K key) {
  969.         final Number answer = getNumber(map, key);
  970.         if (answer == null) {
  971.             return null;
  972.         }
  973.         if (answer instanceof Short) {
  974.             return (Short) answer;
  975.         }
  976.         return Short.valueOf(answer.shortValue());
  977.     }

  978.     /**
  979.      * Looks up the given key in the given map, converting the result into a short, using the defaultFunction to produce
  980.      * the default value if the conversion fails.
  981.      *
  982.      * @param <K> the key type
  983.      * @param map the map whose value to look up
  984.      * @param key the key of the value to look up in that map
  985.      * @param defaultFunction what to produce the default value if the value is null or if the conversion fails
  986.      * @return the value in the map as a number, or defaultValue produced by the defaultFunction if the original value
  987.      *         is null, the map is null or the number conversion fails
  988.      * @since 4.5.0-M1
  989.      */
  990.     public static <K> Short getShort(final Map<? super K, ?> map, final K key,
  991.             final Function<K, Short> defaultFunction) {
  992.         return applyDefaultFunction(map, key, MapUtils::getShort, defaultFunction);
  993.     }

  994.     /**
  995.      * Looks up the given key in the given map, converting the result into a short, using the default value if the
  996.      * conversion fails.
  997.      *
  998.      * @param <K> the key 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 or if the conversion fails
  1002.      * @return the value in the map as a number, or defaultValue if the original value is null, the map is null or the
  1003.      *         number conversion fails
  1004.      */
  1005.     public static <K> Short getShort(final Map<? super K, ?> map, final K key, final Short defaultValue) {
  1006.         return applyDefaultValue(map, key, MapUtils::getShort, defaultValue);
  1007.     }

  1008.     /**
  1009.      * Gets a short from a Map in a null-safe manner.
  1010.      * <p>
  1011.      * The short is obtained from the results of {@link #getNumber(Map,Object)}.
  1012.      * </p>
  1013.      *
  1014.      * @param <K> the key type
  1015.      * @param map the map to use
  1016.      * @param key the key to look up
  1017.      * @return the value in the Map as a short, {@code 0} if null map input
  1018.      */
  1019.     public static <K> short getShortValue(final Map<? super K, ?> map, final K key) {
  1020.         return applyDefaultValue(map, key, MapUtils::getShort, 0).shortValue();
  1021.     }

  1022.     /**
  1023.      * Gets a short from a Map in a null-safe manner, using the default value produced by the defaultFunction if the
  1024.      * conversion fails.
  1025.      * <p>
  1026.      * The short is obtained from the results of {@link #getNumber(Map,Object)}.
  1027.      * </p>
  1028.      *
  1029.      * @param <K> the key type
  1030.      * @param map the map to use
  1031.      * @param key the key to look up
  1032.      * @param defaultFunction produce the default value to return if the value is null or if the conversion fails
  1033.      * @return the value in the Map as a short, default value produced by the {@code defaultFunction} if null map
  1034.      *         input
  1035.      * @since 4.5.0-M1
  1036.      */
  1037.     public static <K> short getShortValue(final Map<? super K, ?> map, final K key,
  1038.             final Function<K, Short> defaultFunction) {
  1039.         return applyDefaultFunction(map, key, MapUtils::getShort, defaultFunction, (short) 0).shortValue();
  1040.     }

  1041.     /**
  1042.      * Gets a short from a Map in a null-safe manner, using the default value if the conversion fails.
  1043.      * <p>
  1044.      * The short is obtained from the results of {@link #getNumber(Map,Object)}.
  1045.      * </p>
  1046.      *
  1047.      * @param <K> the key type
  1048.      * @param map the map to use
  1049.      * @param key the key to look up
  1050.      * @param defaultValue return if the value is null or if the conversion fails
  1051.      * @return the value in the Map as a short, {@code defaultValue} if null map input
  1052.      */
  1053.     public static <K> short getShortValue(final Map<? super K, ?> map, final K key, final short defaultValue) {
  1054.         return applyDefaultValue(map, key, MapUtils::getShort, defaultValue).shortValue();
  1055.     }

  1056.     /**
  1057.      * Gets a String from a Map in a null-safe manner.
  1058.      * <p>
  1059.      * The String is obtained via {@code toString}.
  1060.      * </p>
  1061.      *
  1062.      * @param <K> the key type
  1063.      * @param map the map to use
  1064.      * @param key the key to look up
  1065.      * @return the value in the Map as a String, {@code null} if null map input
  1066.      */
  1067.     public static <K> String getString(final Map<? super K, ?> map, final K key) {
  1068.         if (map != null) {
  1069.             final Object answer = map.get(key);
  1070.             if (answer != null) {
  1071.                 return answer.toString();
  1072.             }
  1073.         }
  1074.         return null;
  1075.     }

  1076.     /**
  1077.      * Looks up the given key in the given map, converting the result into a string, using the defaultFunction to
  1078.      * produce the default value if the conversion fails.
  1079.      *
  1080.      * @param <K> the key type
  1081.      * @param map the map whose value to look up
  1082.      * @param key the key of the value to look up in that map
  1083.      * @param defaultFunction what to produce the default value if the value is null or if the conversion fails
  1084.      * @return the value in the map as a string, or defaultValue produced by the defaultFunction if the original value
  1085.      *         is null, the map is null or the string conversion fails
  1086.      * @since 4.5.0-M1
  1087.      */
  1088.     public static <K> String getString(final Map<? super K, ?> map, final K key,
  1089.             final Function<K, String> defaultFunction) {
  1090.         return applyDefaultFunction(map, key, MapUtils::getString, defaultFunction);
  1091.     }

  1092.     /**
  1093.      * Looks up the given key in the given map, converting the result into a string, using the default value if the
  1094.      * conversion fails.
  1095.      *
  1096.      * @param <K> the key type
  1097.      * @param map the map whose value to look up
  1098.      * @param key the key of the value to look up in that map
  1099.      * @param defaultValue what to return if the value is null or if the conversion fails
  1100.      * @return the value in the map as a string, or defaultValue if the original value is null, the map is null or the
  1101.      *         string conversion fails
  1102.      */
  1103.     public static <K> String getString(final Map<? super K, ?> map, final K key, final String defaultValue) {
  1104.         return applyDefaultValue(map, key, MapUtils::getString, defaultValue);
  1105.     }

  1106.     /**
  1107.      * Inverts the supplied map returning a new HashMap such that the keys of the input are swapped with the values.
  1108.      * <p>
  1109.      * This operation assumes that the inverse mapping is well defined. If the input map had multiple entries with the
  1110.      * same value mapped to different keys, the returned map will map one of those keys to the value, but the exact key
  1111.      * which will be mapped is undefined.
  1112.      * </p>
  1113.      *
  1114.      * @param <K> the key type
  1115.      * @param <V> the value type
  1116.      * @param map the map to invert, must not be null
  1117.      * @return a new HashMap containing the inverted data
  1118.      * @throws NullPointerException if the map is null
  1119.      */
  1120.     public static <K, V> Map<V, K> invertMap(final Map<K, V> map) {
  1121.         Objects.requireNonNull(map, "map");
  1122.         final Map<V, K> out = new HashMap<>(map.size());
  1123.         for (final Entry<K, V> entry : map.entrySet()) {
  1124.             out.put(entry.getValue(), entry.getKey());
  1125.         }
  1126.         return out;
  1127.     }

  1128.     /**
  1129.      * Null-safe check if the specified map is empty.
  1130.      * <p>
  1131.      * Null returns true.
  1132.      * </p>
  1133.      *
  1134.      * @param map the map to check, may be null
  1135.      * @return true if empty or null
  1136.      * @since 3.2
  1137.      */
  1138.     public static boolean isEmpty(final Map<?, ?> map) {
  1139.         return map == null || map.isEmpty();
  1140.     }

  1141.     /**
  1142.      * Null-safe check if the specified map is not empty.
  1143.      * <p>
  1144.      * Null returns false.
  1145.      * </p>
  1146.      *
  1147.      * @param map the map to check, may be null
  1148.      * @return true if non-null and non-empty
  1149.      * @since 3.2
  1150.      */
  1151.     public static boolean isNotEmpty(final Map<?, ?> map) {
  1152.         return !isEmpty(map);
  1153.     }

  1154.     /**
  1155.      * Gets the specified {@link Map} as an {@link IterableMap}.
  1156.      *
  1157.      * @param <K> the key type
  1158.      * @param <V> the value type
  1159.      * @param map to wrap if necessary.
  1160.      * @return IterableMap&lt;K, V&gt;
  1161.      * @throws NullPointerException if map is null
  1162.      * @since 4.0
  1163.      */
  1164.     public static <K, V> IterableMap<K, V> iterableMap(final Map<K, V> map) {
  1165.         Objects.requireNonNull(map, "map");
  1166.         return map instanceof IterableMap ? (IterableMap<K, V>) map : new AbstractMapDecorator<K, V>(map) {
  1167.             // empty
  1168.         };
  1169.     }

  1170.     /**
  1171.      * Gets the specified {@link SortedMap} as an {@link IterableSortedMap}.
  1172.      *
  1173.      * @param <K> the key type
  1174.      * @param <V> the value type
  1175.      * @param sortedMap to wrap if necessary
  1176.      * @return {@link IterableSortedMap}&lt;K, V&gt;
  1177.      * @throws NullPointerException if sortedMap is null
  1178.      * @since 4.0
  1179.      */
  1180.     public static <K, V> IterableSortedMap<K, V> iterableSortedMap(final SortedMap<K, V> sortedMap) {
  1181.         Objects.requireNonNull(sortedMap, "sortedMap");
  1182.         return sortedMap instanceof IterableSortedMap ? (IterableSortedMap<K, V>) sortedMap
  1183.                 : new AbstractSortedMapDecorator<K, V>(sortedMap) {
  1184.                     // empty
  1185.                 };
  1186.     }

  1187.     /**
  1188.      * Returns a "lazy" map whose values will be created on demand.
  1189.      * <p>
  1190.      * When the key passed to the returned map's {@link Map#get(Object)} method is not present in the map, then the
  1191.      * factory will be used to create a new object and that object will become the value associated with that key.
  1192.      * </p>
  1193.      * <p>
  1194.      * For instance:
  1195.      * </p>
  1196.      * <pre>
  1197.      * Factory factory = new Factory() {
  1198.      *     public Object create() {
  1199.      *         return new Date();
  1200.      *     }
  1201.      * }
  1202.      * Map lazyMap = MapUtils.lazyMap(new HashMap(), factory);
  1203.      * Object obj = lazyMap.get("test");
  1204.      * </pre>
  1205.      * <p>
  1206.      * After the above code is executed, {@code obj} will contain a new {@code Date} instance. Furthermore,
  1207.      * that {@code Date} instance is the value for the {@code "test"} key in the map.
  1208.      * </p>
  1209.      *
  1210.      * @param <K> the key type
  1211.      * @param <V> the value type
  1212.      * @param map the map to make lazy, must not be null
  1213.      * @param factory the factory for creating new objects, must not be null
  1214.      * @return a lazy map backed by the given map
  1215.      * @throws NullPointerException if the Map or Factory is null
  1216.      */
  1217.     public static <K, V> IterableMap<K, V> lazyMap(final Map<K, V> map, final Factory<? extends V> factory) {
  1218.         return LazyMap.lazyMap(map, factory);
  1219.     }

  1220.     /**
  1221.      * Returns a "lazy" map whose values will be created on demand.
  1222.      * <p>
  1223.      * When the key passed to the returned map's {@link Map#get(Object)} method is not present in the map, then the
  1224.      * factory will be used to create a new object and that object will become the value associated with that key. The
  1225.      * factory is a {@link Transformer} that will be passed the key which it must transform into the value.
  1226.      * </p>
  1227.      * <p>
  1228.      * For instance:
  1229.      * </p>
  1230.      * <pre>
  1231.      * Transformer factory = new Transformer() {
  1232.      *     public Object transform(Object mapKey) {
  1233.      *         return new File(mapKey);
  1234.      *     }
  1235.      * }
  1236.      * Map lazyMap = MapUtils.lazyMap(new HashMap(), factory);
  1237.      * Object obj = lazyMap.get("C:/dev");
  1238.      * </pre>
  1239.      *
  1240.      * <p>
  1241.      * After the above code is executed, {@code obj} will contain a new {@code File} instance for the C drive
  1242.      * dev directory. Furthermore, that {@code File} instance is the value for the {@code "C:/dev"} key in the
  1243.      * map.
  1244.      * </p>
  1245.      * <p>
  1246.      * If a lazy map is wrapped by a synchronized map, the result is a simple synchronized cache. When an object is not
  1247.      * is the cache, the cache itself calls back to the factory Transformer to populate itself, all within the same
  1248.      * synchronized block.
  1249.      * </p>
  1250.      *
  1251.      * @param <K> the key type
  1252.      * @param <V> the value type
  1253.      * @param map the map to make lazy, must not be null
  1254.      * @param transformerFactory the factory for creating new objects, must not be null
  1255.      * @return a lazy map backed by the given map
  1256.      * @throws NullPointerException if the Map or Transformer is null
  1257.      */
  1258.     public static <K, V> IterableMap<K, V> lazyMap(final Map<K, V> map,
  1259.             final Transformer<? super K, ? extends V> transformerFactory) {
  1260.         return LazyMap.lazyMap(map, transformerFactory);
  1261.     }

  1262.     /**
  1263.      * Returns a "lazy" sorted map whose values will be created on demand.
  1264.      * <p>
  1265.      * When the key passed to the returned map's {@link Map#get(Object)} method is not present in the map, then the
  1266.      * factory will be used to create a new object and that object will become the value associated with that key.
  1267.      * </p>
  1268.      * <p>
  1269.      * For instance:
  1270.      * </p>
  1271.      * <pre>
  1272.      * Factory factory = new Factory() {
  1273.      *     public Object create() {
  1274.      *         return new Date();
  1275.      *     }
  1276.      * }
  1277.      * SortedMap lazy = MapUtils.lazySortedMap(new TreeMap(), factory);
  1278.      * Object obj = lazy.get("test");
  1279.      * </pre>
  1280.      * <p>
  1281.      * After the above code is executed, {@code obj} will contain a new {@code Date} instance. Furthermore,
  1282.      * that {@code Date} instance is the value for the {@code "test"} key.
  1283.      * </p>
  1284.      *
  1285.      * @param <K> the key type
  1286.      * @param <V> the value type
  1287.      * @param map the map to make lazy, must not be null
  1288.      * @param factory the factory for creating new objects, must not be null
  1289.      * @return a lazy map backed by the given map
  1290.      * @throws NullPointerException if the SortedMap or Factory is null
  1291.      */
  1292.     public static <K, V> SortedMap<K, V> lazySortedMap(final SortedMap<K, V> map, final Factory<? extends V> factory) {
  1293.         return LazySortedMap.lazySortedMap(map, factory);
  1294.     }

  1295.     /**
  1296.      * Returns a "lazy" sorted map whose values will be created on demand.
  1297.      * <p>
  1298.      * When the key passed to the returned map's {@link Map#get(Object)} method is not present in the map, then the
  1299.      * factory will be used to create a new object and that object will become the value associated with that key. The
  1300.      * factory is a {@link Transformer} that will be passed the key which it must transform into the value.
  1301.      * </p>
  1302.      * <p>
  1303.      * For instance:
  1304.      * </p>
  1305.      * <pre>
  1306.      * Transformer factory = new Transformer() {
  1307.      *     public Object transform(Object mapKey) {
  1308.      *         return new File(mapKey);
  1309.      *     }
  1310.      * }
  1311.      * SortedMap lazy = MapUtils.lazySortedMap(new TreeMap(), factory);
  1312.      * Object obj = lazy.get("C:/dev");
  1313.      * </pre>
  1314.      * <p>
  1315.      * After the above code is executed, {@code obj} will contain a new {@code File} instance for the C drive
  1316.      * dev directory. Furthermore, that {@code File} instance is the value for the {@code "C:/dev"} key in the
  1317.      * map.
  1318.      * </p>
  1319.      * <p>
  1320.      * If a lazy map is wrapped by a synchronized map, the result is a simple synchronized cache. When an object is not
  1321.      * is the cache, the cache itself calls back to the factory Transformer to populate itself, all within the same
  1322.      * synchronized block.
  1323.      * </p>
  1324.      *
  1325.      * @param <K> the key type
  1326.      * @param <V> the value type
  1327.      * @param map the map to make lazy, must not be null
  1328.      * @param transformerFactory the factory for creating new objects, must not be null
  1329.      * @return a lazy map backed by the given map
  1330.      * @throws NullPointerException if the Map or Transformer is null
  1331.      */
  1332.     public static <K, V> SortedMap<K, V> lazySortedMap(final SortedMap<K, V> map,
  1333.             final Transformer<? super K, ? extends V> transformerFactory) {
  1334.         return LazySortedMap.lazySortedMap(map, transformerFactory);
  1335.     }

  1336.     /**
  1337.      * Creates a multi-value map backed by the given map which returns collections of type ArrayList.
  1338.      *
  1339.      * @param <K> the key type
  1340.      * @param <V> the value type
  1341.      * @param map the map to decorate
  1342.      * @return a multi-value map backed by the given map which returns ArrayLists of values.
  1343.      * @see MultiValueMap
  1344.      * @since 3.2
  1345.      * @deprecated since 4.1, use {@link MultiValuedMap} instead
  1346.      */
  1347.     @Deprecated
  1348.     public static <K, V> MultiValueMap<K, V> multiValueMap(final Map<K, ? super Collection<V>> map) {
  1349.         return MultiValueMap.<K, V>multiValueMap(map);
  1350.     }

  1351.     /**
  1352.      * Creates a multi-value map backed by the given map which returns collections of the specified type.
  1353.      *
  1354.      * @param <K> the key type
  1355.      * @param <V> the value type
  1356.      * @param <C> the collection class type
  1357.      * @param map the map to decorate
  1358.      * @param collectionClass the type of collections to return from the map (must contain public no-arg constructor and
  1359.      *        extend Collection)
  1360.      * @return a multi-value map backed by the given map which returns collections of the specified type
  1361.      * @see MultiValueMap
  1362.      * @since 3.2
  1363.      * @deprecated since 4.1, use {@link MultiValuedMap} instead
  1364.      */
  1365.     @Deprecated
  1366.     public static <K, V, C extends Collection<V>> MultiValueMap<K, V> multiValueMap(final Map<K, C> map,
  1367.             final Class<C> collectionClass) {
  1368.         return MultiValueMap.multiValueMap(map, collectionClass);
  1369.     }

  1370.     /**
  1371.      * Creates a multi-value map backed by the given map which returns collections created by the specified collection
  1372.      * factory.
  1373.      *
  1374.      * @param <K> the key type
  1375.      * @param <V> the value type
  1376.      * @param <C> the collection class type
  1377.      * @param map the map to decorate
  1378.      * @param collectionFactory a factor which creates collection objects
  1379.      * @return a multi-value map backed by the given map which returns collections created by the specified collection
  1380.      *         factory
  1381.      * @see MultiValueMap
  1382.      * @since 3.2
  1383.      * @deprecated since 4.1, use {@link MultiValuedMap} instead
  1384.      */
  1385.     @Deprecated
  1386.     public static <K, V, C extends Collection<V>> MultiValueMap<K, V> multiValueMap(final Map<K, C> map,
  1387.             final Factory<C> collectionFactory) {
  1388.         return MultiValueMap.multiValueMap(map, collectionFactory);
  1389.     }

  1390.     /**
  1391.      * Returns a map that maintains the order of keys that are added backed by the given map.
  1392.      * <p>
  1393.      * If a key is added twice, the order is determined by the first add. The order is observed through the keySet,
  1394.      * values and entrySet.
  1395.      * </p>
  1396.      *
  1397.      * @param <K> the key type
  1398.      * @param <V> the value type
  1399.      * @param map the map to order, must not be null
  1400.      * @return an ordered map backed by the given map
  1401.      * @throws NullPointerException if the Map is null
  1402.      */
  1403.     public static <K, V> OrderedMap<K, V> orderedMap(final Map<K, V> map) {
  1404.         return ListOrderedMap.listOrderedMap(map);
  1405.     }

  1406.     /**
  1407.      * Populates a Map using the supplied {@code Transformer}s to transform the elements into keys and values.
  1408.      *
  1409.      * @param <K> the key type
  1410.      * @param <V> the value type
  1411.      * @param <E> the type of object contained in the {@link Iterable}
  1412.      * @param map the {@code Map} to populate.
  1413.      * @param elements the {@code Iterable} containing the input values for the map.
  1414.      * @param keyTransformer the {@code Transformer} used to transform the element into a key value
  1415.      * @param valueTransformer the {@code Transformer} used to transform the element into a value
  1416.      * @throws NullPointerException if the map, elements or transformers are null
  1417.      */
  1418.     public static <K, V, E> void populateMap(final Map<K, V> map, final Iterable<? extends E> elements,
  1419.             final Transformer<E, K> keyTransformer, final Transformer<E, V> valueTransformer) {
  1420.         for (final E temp : elements) {
  1421.             map.put(keyTransformer.apply(temp), valueTransformer.apply(temp));
  1422.         }
  1423.     }

  1424.     /**
  1425.      * Populates a Map using the supplied {@code Transformer} to transform the elements into keys, using the
  1426.      * unaltered element as the value in the {@code Map}.
  1427.      *
  1428.      * @param <K> the key type
  1429.      * @param <V> the value type
  1430.      * @param map the {@code Map} to populate.
  1431.      * @param elements the {@code Iterable} containing the input values for the map.
  1432.      * @param keyTransformer the {@code Transformer} used to transform the element into a key value
  1433.      * @throws NullPointerException if the map, elements or transformer are null
  1434.      */
  1435.     public static <K, V> void populateMap(final Map<K, V> map, final Iterable<? extends V> elements,
  1436.             final Transformer<V, K> keyTransformer) {
  1437.         populateMap(map, elements, keyTransformer, TransformerUtils.<V>nopTransformer());
  1438.     }

  1439.     /**
  1440.      * Populates a MultiMap using the supplied {@code Transformer}s to transform the elements into keys and values.
  1441.      *
  1442.      * @param <K> the key type
  1443.      * @param <V> the value type
  1444.      * @param <E> the type of object contained in the {@link Iterable}
  1445.      * @param map the {@code MultiMap} to populate.
  1446.      * @param elements the {@code Iterable} containing the input values for the map.
  1447.      * @param keyTransformer the {@code Transformer} used to transform the element into a key value
  1448.      * @param valueTransformer the {@code Transformer} used to transform the element into a value
  1449.      * @throws NullPointerException if the map, collection or transformers are null
  1450.      */
  1451.     public static <K, V, E> void populateMap(final MultiMap<K, V> map, final Iterable<? extends E> elements,
  1452.             final Transformer<E, K> keyTransformer, final Transformer<E, V> valueTransformer) {
  1453.         for (final E temp : elements) {
  1454.             map.put(keyTransformer.apply(temp), valueTransformer.apply(temp));
  1455.         }
  1456.     }

  1457.     /**
  1458.      * Populates a MultiMap using the supplied {@code Transformer} to transform the elements into keys, using the
  1459.      * unaltered element as the value in the {@code MultiMap}.
  1460.      *
  1461.      * @param <K> the key type
  1462.      * @param <V> the value type
  1463.      * @param map the {@code MultiMap} to populate.
  1464.      * @param elements the {@code Iterable} to use as input values for the map.
  1465.      * @param keyTransformer the {@code Transformer} used to transform the element into a key value
  1466.      * @throws NullPointerException if the map, elements or transformer are null
  1467.      */
  1468.     public static <K, V> void populateMap(final MultiMap<K, V> map, final Iterable<? extends V> elements,
  1469.             final Transformer<V, K> keyTransformer) {
  1470.         populateMap(map, elements, keyTransformer, TransformerUtils.<V>nopTransformer());
  1471.     }

  1472.     /**
  1473.      * Returns a predicated (validating) map backed by the given map.
  1474.      * <p>
  1475.      * Only objects that pass the tests in the given predicates can be added to the map. Trying to add an invalid object
  1476.      * results in an IllegalArgumentException. Keys must pass the key predicate, values must pass the value predicate.
  1477.      * It is important not to use the original map after invoking this method, as it is a backdoor for adding invalid
  1478.      * objects.
  1479.      * </p>
  1480.      *
  1481.      * @param <K> the key type
  1482.      * @param <V> the value type
  1483.      * @param map the map to predicate, must not be null
  1484.      * @param keyPred the predicate for keys, null means no check
  1485.      * @param valuePred the predicate for values, null means no check
  1486.      * @return a predicated map backed by the given map
  1487.      * @throws NullPointerException if the Map is null
  1488.      */
  1489.     public static <K, V> IterableMap<K, V> predicatedMap(final Map<K, V> map, final Predicate<? super K> keyPred,
  1490.             final Predicate<? super V> valuePred) {
  1491.         return PredicatedMap.predicatedMap(map, keyPred, valuePred);
  1492.     }

  1493.     /**
  1494.      * Returns a predicated (validating) sorted map backed by the given map.
  1495.      * <p>
  1496.      * Only objects that pass the tests in the given predicates can be added to the map. Trying to add an invalid object
  1497.      * results in an IllegalArgumentException. Keys must pass the key predicate, values must pass the value predicate.
  1498.      * It is important not to use the original map after invoking this method, as it is a backdoor for adding invalid
  1499.      * objects.
  1500.      * </p>
  1501.      *
  1502.      * @param <K> the key type
  1503.      * @param <V> the value type
  1504.      * @param map the map to predicate, must not be null
  1505.      * @param keyPred the predicate for keys, null means no check
  1506.      * @param valuePred the predicate for values, null means no check
  1507.      * @return a predicated map backed by the given map
  1508.      * @throws NullPointerException if the SortedMap is null
  1509.      */
  1510.     public static <K, V> SortedMap<K, V> predicatedSortedMap(final SortedMap<K, V> map,
  1511.             final Predicate<? super K> keyPred, final Predicate<? super V> valuePred) {
  1512.         return PredicatedSortedMap.predicatedSortedMap(map, keyPred, valuePred);
  1513.     }

  1514.     /**
  1515.      * Writes indentation to the given stream.
  1516.      *
  1517.      * @param out the stream to indent
  1518.      * @param indent the index of the indentation
  1519.      */
  1520.     private static void printIndent(final PrintStream out, final int indent) {
  1521.         for (int i = 0; i < indent; i++) {
  1522.             out.print(INDENT_STRING);
  1523.         }
  1524.     }

  1525.     /**
  1526.      * Puts all the keys and values from the specified array into the map.
  1527.      * <p>
  1528.      * This method is an alternative to the {@link Map#putAll(java.util.Map)} method and constructors. It
  1529.      * allows you to build a map from an object array of various possible styles.
  1530.      * </p>
  1531.      * <p>
  1532.      * If the first entry in the object array implements {@link Map.Entry} or {@link KeyValue} then the key
  1533.      * and value are added from that object. If the first entry in the object array is an object array itself, then it
  1534.      * is assumed that index 0 in the sub-array is the key and index 1 is the value. Otherwise, the array is treated as
  1535.      * keys and values in alternate indices.
  1536.      * </p>
  1537.      * <p>
  1538.      * For example, to create a color map:
  1539.      * </p>
  1540.      * <pre>
  1541.      * Map colorMap = MapUtils.putAll(new HashMap(),
  1542.      *         new String[][] { { "RED", "#FF0000" }, { "GREEN", "#00FF00" }, { "BLUE", "#0000FF" } });
  1543.      * </pre>
  1544.      * <p>
  1545.      * or:
  1546.      * </p>
  1547.      * <pre>
  1548.      * Map colorMap = MapUtils.putAll(new HashMap(),
  1549.      *         new String[] { "RED", "#FF0000", "GREEN", "#00FF00", "BLUE", "#0000FF" });
  1550.      * </pre>
  1551.      * <p>
  1552.      * or:
  1553.      * </p>
  1554.      * <pre>
  1555.      * Map colorMap = MapUtils.putAll(new HashMap(), new Map.Entry[] { new DefaultMapEntry("RED", "#FF0000"),
  1556.      *         new DefaultMapEntry("GREEN", "#00FF00"), new DefaultMapEntry("BLUE", "#0000FF") });
  1557.      * </pre>
  1558.      *
  1559.      * @param <K> the key type
  1560.      * @param <V> the value type
  1561.      * @param map the map to populate, must not be null
  1562.      * @param array an array to populate from, null ignored
  1563.      * @return the input map
  1564.      * @throws NullPointerException if map is null
  1565.      * @throws IllegalArgumentException if sub-array or entry matching used and an entry is invalid
  1566.      * @throws ClassCastException if the array contents is mixed
  1567.      * @since 3.2
  1568.      */
  1569.     @SuppressWarnings("unchecked") // As per Javadoc throws CCE for invalid array contents
  1570.     public static <K, V> Map<K, V> putAll(final Map<K, V> map, final Object[] array) {
  1571.         Objects.requireNonNull(map, "map");
  1572.         if (array == null || array.length == 0) {
  1573.             return map;
  1574.         }
  1575.         final Object obj = array[0];
  1576.         if (obj instanceof Map.Entry) {
  1577.             for (final Object element : array) {
  1578.                 // cast ok here, type is checked above
  1579.                 final Map.Entry<K, V> entry = (Map.Entry<K, V>) element;
  1580.                 map.put(entry.getKey(), entry.getValue());
  1581.             }
  1582.         } else if (obj instanceof KeyValue) {
  1583.             for (final Object element : array) {
  1584.                 // cast ok here, type is checked above
  1585.                 final KeyValue<K, V> keyval = (KeyValue<K, V>) element;
  1586.                 map.put(keyval.getKey(), keyval.getValue());
  1587.             }
  1588.         } else if (obj instanceof Object[]) {
  1589.             for (int i = 0; i < array.length; i++) {
  1590.                 final Object[] sub = (Object[]) array[i];
  1591.                 if (sub == null || sub.length < 2) {
  1592.                     throw new IllegalArgumentException("Invalid array element: " + i);
  1593.                 }
  1594.                 // these casts can fail if array has incorrect types
  1595.                 map.put((K) sub[0], (V) sub[1]);
  1596.             }
  1597.         } else {
  1598.             for (int i = 0; i < array.length - 1;) {
  1599.                 // these casts can fail if array has incorrect types
  1600.                 map.put((K) array[i++], (V) array[i++]);
  1601.             }
  1602.         }
  1603.         return map;
  1604.     }

  1605.     /**
  1606.      * Protects against adding null values to a map.
  1607.      * <p>
  1608.      * This method checks the value being added to the map, and if it is null it is replaced by an empty string.
  1609.      * </p>
  1610.      * <p>
  1611.      * This could be useful if the map does not accept null values, or for receiving data from a source that may provide
  1612.      * null or empty string which should be held in the same way in the map.
  1613.      * </p>
  1614.      * <p>
  1615.      * Keys are not validated. Note that this method can be used to circumvent the map's value type at runtime.
  1616.      * </p>
  1617.      *
  1618.      * @param <K> the key type
  1619.      * @param map the map to add to, must not be null
  1620.      * @param key the key
  1621.      * @param value the value, null converted to ""
  1622.      * @throws NullPointerException if the map is null
  1623.      */
  1624.     public static <K> void safeAddToMap(final Map<? super K, Object> map, final K key, final Object value)
  1625.             throws NullPointerException {
  1626.         Objects.requireNonNull(map, "map");
  1627.         map.put(key, value == null ? "" : value);
  1628.     }

  1629.     /**
  1630.      * Gets the given map size or 0 if the map is null
  1631.      *
  1632.      * @param map a Map or null
  1633.      * @return the given map size or 0 if the map is null
  1634.      */
  1635.     public static int size(final Map<?, ?> map) {
  1636.         return map == null ? 0 : map.size();
  1637.     }

  1638.     /**
  1639.      * Returns a synchronized map backed by the given map.
  1640.      * <p>
  1641.      * You must manually synchronize on the returned buffer's iterator to avoid non-deterministic behavior:
  1642.      * </p>
  1643.      * <pre>
  1644.      * Map m = MapUtils.synchronizedMap(myMap);
  1645.      * Sets s = m.keySet(); // outside synchronized block
  1646.      * synchronized (m) { // synchronized on MAP!
  1647.      *     Iterator i = s.iterator();
  1648.      *     while (i.hasNext()) {
  1649.      *         process(i.next());
  1650.      *     }
  1651.      * }
  1652.      * </pre>
  1653.      * <p>
  1654.      * This method uses the implementation in {@link java.util.Collections Collections}.
  1655.      * </p>
  1656.      *
  1657.      * @param <K> the key type
  1658.      * @param <V> the value type
  1659.      * @param map the map to synchronize, must not be null
  1660.      * @return a synchronized map backed by the given map
  1661.      */
  1662.     public static <K, V> Map<K, V> synchronizedMap(final Map<K, V> map) {
  1663.         return Collections.synchronizedMap(map);
  1664.     }

  1665.     /**
  1666.      * Returns a synchronized sorted map backed by the given sorted map.
  1667.      * <p>
  1668.      * You must manually synchronize on the returned buffer's iterator to avoid non-deterministic behavior:
  1669.      * </p>
  1670.      * <pre>
  1671.      * Map m = MapUtils.synchronizedSortedMap(myMap);
  1672.      * Sets s = m.keySet(); // outside synchronized block
  1673.      * synchronized (m) { // synchronized on MAP!
  1674.      *     Iterator i = s.iterator();
  1675.      *     while (i.hasNext()) {
  1676.      *         process(i.next());
  1677.      *     }
  1678.      * }
  1679.      * </pre>
  1680.      * <p>
  1681.      * This method uses the implementation in {@link java.util.Collections Collections}.
  1682.      * </p>
  1683.      *
  1684.      * @param <K> the key type
  1685.      * @param <V> the value type
  1686.      * @param map the map to synchronize, must not be null
  1687.      * @return a synchronized map backed by the given map
  1688.      * @throws NullPointerException if the map is null
  1689.      */
  1690.     public static <K, V> SortedMap<K, V> synchronizedSortedMap(final SortedMap<K, V> map) {
  1691.         return Collections.synchronizedSortedMap(map);
  1692.     }

  1693.     /**
  1694.      * Creates a new HashMap using data copied from a ResourceBundle.
  1695.      *
  1696.      * @param resourceBundle the resource bundle to convert, must not be null
  1697.      * @return the HashMap containing the data
  1698.      * @throws NullPointerException if the bundle is null
  1699.      */
  1700.     public static Map<String, Object> toMap(final ResourceBundle resourceBundle) {
  1701.         Objects.requireNonNull(resourceBundle, "resourceBundle");
  1702.         final Enumeration<String> enumeration = resourceBundle.getKeys();
  1703.         final Map<String, Object> map = new HashMap<>();

  1704.         while (enumeration.hasMoreElements()) {
  1705.             final String key = enumeration.nextElement();
  1706.             final Object value = resourceBundle.getObject(key);
  1707.             map.put(key, value);
  1708.         }

  1709.         return map;
  1710.     }

  1711.     /**
  1712.      * Gets a new Properties object initialized with the values from a Map. A null input will return an empty properties
  1713.      * object.
  1714.      * <p>
  1715.      * A Properties object may only store non-null keys and values, thus if the provided map contains either a key or
  1716.      * value which is {@code null}, a {@link NullPointerException} will be thrown.
  1717.      * </p>
  1718.      *
  1719.      * @param <K> the key type
  1720.      * @param <V> the value type
  1721.      * @param map the map to convert to a Properties object
  1722.      * @return the properties object
  1723.      * @throws NullPointerException if a key or value in the provided map is {@code null}
  1724.      */
  1725.     public static <K, V> Properties toProperties(final Map<K, V> map) {
  1726.         final Properties answer = new Properties();
  1727.         if (map != null) {
  1728.             for (final Entry<K, V> entry2 : map.entrySet()) {
  1729.                 final Map.Entry<?, ?> entry = entry2;
  1730.                 final Object key = entry.getKey();
  1731.                 final Object value = entry.getValue();
  1732.                 answer.put(key, value);
  1733.             }
  1734.         }
  1735.         return answer;
  1736.     }

  1737.     /**
  1738.      * Returns a transformed map backed by the given map.
  1739.      * <p>
  1740.      * This method returns a new map (decorating the specified map) that will transform any new entries added to it.
  1741.      * Existing entries in the specified map will not be transformed. If you want that behavior, see
  1742.      * {@link TransformedMap#transformedMap}.
  1743.      * </p>
  1744.      * <p>
  1745.      * Each object is passed through the transformers as it is added to the Map. It is important not to use the original
  1746.      * map after invoking this method, as it is a backdoor for adding untransformed objects.
  1747.      * </p>
  1748.      * <p>
  1749.      * If there are any elements already in the map being decorated, they are NOT transformed.
  1750.      * </p>
  1751.      *
  1752.      * @param <K> the key type
  1753.      * @param <V> the value type
  1754.      * @param map the map to transform, must not be null, typically empty
  1755.      * @param keyTransformer the transformer for the map keys, null means no transformation
  1756.      * @param valueTransformer the transformer for the map values, null means no transformation
  1757.      * @return a transformed map backed by the given map
  1758.      * @throws NullPointerException if the Map is null
  1759.      */
  1760.     public static <K, V> IterableMap<K, V> transformedMap(final Map<K, V> map,
  1761.             final Transformer<? super K, ? extends K> keyTransformer,
  1762.             final Transformer<? super V, ? extends V> valueTransformer) {
  1763.         return TransformedMap.transformingMap(map, keyTransformer, valueTransformer);
  1764.     }

  1765.     /**
  1766.      * Returns a transformed sorted map backed by the given map.
  1767.      * <p>
  1768.      * This method returns a new sorted map (decorating the specified map) that will transform any new entries added to
  1769.      * it. Existing entries in the specified map will not be transformed. If you want that behavior, see
  1770.      * {@link TransformedSortedMap#transformedSortedMap}.
  1771.      * </p>
  1772.      * <p>
  1773.      * Each object is passed through the transformers as it is added to the Map. It is important not to use the original
  1774.      * map after invoking this method, as it is a backdoor for adding untransformed objects.
  1775.      * </p>
  1776.      * <p>
  1777.      * If there are any elements already in the map being decorated, they are NOT transformed.
  1778.      * </p>
  1779.      *
  1780.      * @param <K> the key type
  1781.      * @param <V> the value type
  1782.      * @param map the map to transform, must not be null, typically empty
  1783.      * @param keyTransformer the transformer for the map keys, null means no transformation
  1784.      * @param valueTransformer the transformer for the map values, null means no transformation
  1785.      * @return a transformed map backed by the given map
  1786.      * @throws NullPointerException if the SortedMap is null
  1787.      */
  1788.     public static <K, V> SortedMap<K, V> transformedSortedMap(final SortedMap<K, V> map,
  1789.             final Transformer<? super K, ? extends K> keyTransformer,
  1790.             final Transformer<? super V, ? extends V> valueTransformer) {
  1791.         return TransformedSortedMap.transformingSortedMap(map, keyTransformer, valueTransformer);
  1792.     }

  1793.     /**
  1794.      * Returns an unmodifiable map backed by the given map.
  1795.      * <p>
  1796.      * This method uses the implementation in the decorators subpackage.
  1797.      * </p>
  1798.      *
  1799.      * @param <K> the key type
  1800.      * @param <V> the value type
  1801.      * @param map the map to make unmodifiable, must not be null
  1802.      * @return an unmodifiable map backed by the given map
  1803.      * @throws NullPointerException if the map is null
  1804.      */
  1805.     public static <K, V> Map<K, V> unmodifiableMap(final Map<? extends K, ? extends V> map) {
  1806.         return UnmodifiableMap.unmodifiableMap(map);
  1807.     }

  1808.     /**
  1809.      * Returns an unmodifiable sorted map backed by the given sorted map.
  1810.      * <p>
  1811.      * This method uses the implementation in the decorators subpackage.
  1812.      * </p>
  1813.      *
  1814.      * @param <K> the key type
  1815.      * @param <V> the value type
  1816.      * @param map the sorted map to make unmodifiable, must not be null
  1817.      * @return an unmodifiable map backed by the given map
  1818.      * @throws NullPointerException if the map is null
  1819.      */
  1820.     public static <K, V> SortedMap<K, V> unmodifiableSortedMap(final SortedMap<K, ? extends V> map) {
  1821.         return UnmodifiableSortedMap.unmodifiableSortedMap(map);
  1822.     }

  1823.     /**
  1824.      * Prints the given map with nice line breaks.
  1825.      * <p>
  1826.      * This method prints a nicely formatted String describing the Map. Each map entry will be printed with key and
  1827.      * value. When the value is a Map, recursive behavior occurs.
  1828.      * </p>
  1829.      * <p>
  1830.      * This method is NOT thread-safe in any special way. You must manually synchronize on either this class or the
  1831.      * stream as required.
  1832.      * </p>
  1833.      *
  1834.      * @param out the stream to print to, must not be null
  1835.      * @param label The label to be used, may be {@code null}. If {@code null}, the label is not output. It
  1836.      *        typically represents the name of the property in a bean or similar.
  1837.      * @param map The map to print, may be {@code null}. If {@code null}, the text 'null' is output.
  1838.      * @throws NullPointerException if the stream is {@code null}
  1839.      */
  1840.     public static void verbosePrint(final PrintStream out, final Object label, final Map<?, ?> map) {
  1841.         verbosePrintInternal(out, label, map, new ArrayDeque<>(), false);
  1842.     }

  1843.     /**
  1844.      * Implementation providing functionality for {@link #debugPrint} and for {@link #verbosePrint}. This prints the
  1845.      * given map with nice line breaks. If the debug flag is true, it additionally prints the type of the object value.
  1846.      * If the contents of a map include the map itself, then the text <em>(this Map)</em> is printed out. If the
  1847.      * contents include a parent container of the map, the text <em>(ancestor[i] Map)</em> is printed, where it actually
  1848.      * indicates the number of levels which must be traversed in the sequential list of ancestors (for example father,
  1849.      * grandfather, great-grandfather, etc.).
  1850.      *
  1851.      * @param out the stream to print to
  1852.      * @param label the label to be used, may be {@code null}. If {@code null}, the label is not output. It
  1853.      *        typically represents the name of the property in a bean or similar.
  1854.      * @param map the map to print, may be {@code null}. If {@code null}, the text 'null' is output
  1855.      * @param lineage a stack consisting of any maps in which the previous argument is contained. This is checked to
  1856.      *        avoid infinite recursion when printing the output
  1857.      * @param debug flag indicating whether type names should be output.
  1858.      * @throws NullPointerException if the stream is {@code null}
  1859.      */
  1860.     private static void verbosePrintInternal(final PrintStream out, final Object label, final Map<?, ?> map,
  1861.             final Deque<Map<?, ?>> lineage, final boolean debug) {
  1862.         printIndent(out, lineage.size());

  1863.         if (map == null) {
  1864.             if (label != null) {
  1865.                 out.print(label);
  1866.                 out.print(" = ");
  1867.             }
  1868.             out.println("null");
  1869.             return;
  1870.         }
  1871.         if (label != null) {
  1872.             out.print(label);
  1873.             out.println(" = ");
  1874.         }

  1875.         printIndent(out, lineage.size());
  1876.         out.println("{");

  1877.         lineage.addLast(map);

  1878.         for (final Map.Entry<?, ?> entry : map.entrySet()) {
  1879.             final Object childKey = entry.getKey();
  1880.             final Object childValue = entry.getValue();
  1881.             if (childValue instanceof Map && !lineage.contains(childValue)) {
  1882.                 verbosePrintInternal(out, childKey == null ? "null" : childKey, (Map<?, ?>) childValue, lineage, debug);
  1883.             } else {
  1884.                 printIndent(out, lineage.size());
  1885.                 out.print(childKey);
  1886.                 out.print(" = ");

  1887.                 final int lineageIndex = IterableUtils.indexOf(lineage, PredicateUtils.equalPredicate(childValue));
  1888.                 if (lineageIndex == -1) {
  1889.                     out.print(childValue);
  1890.                 } else if (lineage.size() - 1 == lineageIndex) {
  1891.                     out.print("(this Map)");
  1892.                 } else {
  1893.                     out.print("(ancestor[" + (lineage.size() - 1 - lineageIndex - 1) + "] Map)");
  1894.                 }

  1895.                 if (debug && childValue != null) {
  1896.                     out.print(' ');
  1897.                     out.println(childValue.getClass().getName());
  1898.                 } else {
  1899.                     out.println();
  1900.                 }
  1901.             }
  1902.         }

  1903.         lineage.removeLast();

  1904.         printIndent(out, lineage.size());
  1905.         out.println(debug ? "} " + map.getClass().getName() : "}");
  1906.     }

  1907.     /**
  1908.      * Don't allow instances.
  1909.      */
  1910.     private MapUtils() {
  1911.     }

  1912. }