View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.collections4;
18  
19  import java.io.PrintStream;
20  import java.text.NumberFormat;
21  import java.text.ParseException;
22  import java.util.ArrayDeque;
23  import java.util.Collection;
24  import java.util.Collections;
25  import java.util.Deque;
26  import java.util.Enumeration;
27  import java.util.HashMap;
28  import java.util.Map;
29  import java.util.Map.Entry;
30  import java.util.Objects;
31  import java.util.Properties;
32  import java.util.ResourceBundle;
33  import java.util.SortedMap;
34  import java.util.TreeMap;
35  import java.util.function.BiFunction;
36  import java.util.function.Function;
37  
38  import org.apache.commons.collections4.map.AbstractMapDecorator;
39  import org.apache.commons.collections4.map.AbstractSortedMapDecorator;
40  import org.apache.commons.collections4.map.FixedSizeMap;
41  import org.apache.commons.collections4.map.FixedSizeSortedMap;
42  import org.apache.commons.collections4.map.LazyMap;
43  import org.apache.commons.collections4.map.LazySortedMap;
44  import org.apache.commons.collections4.map.ListOrderedMap;
45  import org.apache.commons.collections4.map.MultiValueMap;
46  import org.apache.commons.collections4.map.PredicatedMap;
47  import org.apache.commons.collections4.map.PredicatedSortedMap;
48  import org.apache.commons.collections4.map.TransformedMap;
49  import org.apache.commons.collections4.map.TransformedSortedMap;
50  import org.apache.commons.collections4.map.UnmodifiableMap;
51  import org.apache.commons.collections4.map.UnmodifiableSortedMap;
52  
53  /**
54   * Provides utility methods and decorators for {@link Map} and {@link SortedMap} instances.
55   * <p>
56   * It contains various type safe methods as well as other useful features like deep copying.
57   * </p>
58   * <p>
59   * It also provides the following decorators:
60   * </p>
61   *
62   * <ul>
63   * <li>{@link #fixedSizeMap(Map)}
64   * <li>{@link #fixedSizeSortedMap(SortedMap)}
65   * <li>{@link #lazyMap(Map,Factory)}
66   * <li>{@link #lazyMap(Map,Transformer)}
67   * <li>{@link #lazySortedMap(SortedMap,Factory)}
68   * <li>{@link #lazySortedMap(SortedMap,Transformer)}
69   * <li>{@link #predicatedMap(Map,Predicate,Predicate)}
70   * <li>{@link #predicatedSortedMap(SortedMap,Predicate,Predicate)}
71   * <li>{@link #transformedMap(Map, Transformer, Transformer)}
72   * <li>{@link #transformedSortedMap(SortedMap, Transformer, Transformer)}
73   * <li>{@link #multiValueMap( Map )}
74   * <li>{@link #multiValueMap( Map, Class )}
75   * <li>{@link #multiValueMap( Map, Factory )}
76   * </ul>
77   *
78   * @since 1.0
79   */
80  @SuppressWarnings("deprecation")
81  public class MapUtils {
82  
83      /**
84       * An empty unmodifiable sorted map. This is not provided in the JDK.
85       */
86      @SuppressWarnings("rawtypes")
87      public static final SortedMap EMPTY_SORTED_MAP = UnmodifiableSortedMap.unmodifiableSortedMap(new TreeMap<>());
88  
89      /**
90       * String used to indent the verbose and debug Map prints.
91       */
92      private static final String INDENT_STRING = "    ";
93  
94      /**
95       * Applies the {@code getFunction} and returns its result if non-null, if null returns the result of applying the
96       * default function.
97       *
98       * @param <K> The key type.
99       * @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 !MapUtils.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 }