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