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