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