001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.collections4; 018 019import java.io.PrintStream; 020import java.text.NumberFormat; 021import java.text.ParseException; 022import java.util.ArrayDeque; 023import java.util.Collection; 024import java.util.Collections; 025import java.util.Deque; 026import java.util.Enumeration; 027import java.util.HashMap; 028import java.util.Map; 029import java.util.Map.Entry; 030import java.util.Objects; 031import java.util.Properties; 032import java.util.ResourceBundle; 033import java.util.SortedMap; 034import java.util.TreeMap; 035import java.util.function.BiFunction; 036import java.util.function.Function; 037 038import org.apache.commons.collections4.map.AbstractMapDecorator; 039import org.apache.commons.collections4.map.AbstractSortedMapDecorator; 040import org.apache.commons.collections4.map.FixedSizeMap; 041import org.apache.commons.collections4.map.FixedSizeSortedMap; 042import org.apache.commons.collections4.map.LazyMap; 043import org.apache.commons.collections4.map.LazySortedMap; 044import org.apache.commons.collections4.map.ListOrderedMap; 045import org.apache.commons.collections4.map.MultiValueMap; 046import org.apache.commons.collections4.map.PredicatedMap; 047import org.apache.commons.collections4.map.PredicatedSortedMap; 048import org.apache.commons.collections4.map.TransformedMap; 049import org.apache.commons.collections4.map.TransformedSortedMap; 050import org.apache.commons.collections4.map.UnmodifiableMap; 051import org.apache.commons.collections4.map.UnmodifiableSortedMap; 052 053/** 054 * Provides utility methods and decorators for {@link Map} and {@link SortedMap} instances. 055 * <p> 056 * It contains various type safe methods as well as other useful features like deep copying. 057 * </p> 058 * <p> 059 * It also provides the following decorators: 060 * </p> 061 * 062 * <ul> 063 * <li>{@link #fixedSizeMap(Map)} 064 * <li>{@link #fixedSizeSortedMap(SortedMap)} 065 * <li>{@link #lazyMap(Map,Factory)} 066 * <li>{@link #lazyMap(Map,Transformer)} 067 * <li>{@link #lazySortedMap(SortedMap,Factory)} 068 * <li>{@link #lazySortedMap(SortedMap,Transformer)} 069 * <li>{@link #predicatedMap(Map,Predicate,Predicate)} 070 * <li>{@link #predicatedSortedMap(SortedMap,Predicate,Predicate)} 071 * <li>{@link #transformedMap(Map, Transformer, Transformer)} 072 * <li>{@link #transformedSortedMap(SortedMap, Transformer, Transformer)} 073 * <li>{@link #multiValueMap( Map )} 074 * <li>{@link #multiValueMap( Map, Class )} 075 * <li>{@link #multiValueMap( Map, Factory )} 076 * </ul> 077 * 078 * @since 1.0 079 */ 080@SuppressWarnings("deprecation") 081public class MapUtils { 082 083 /** 084 * An empty unmodifiable sorted map. This is not provided in the JDK. 085 */ 086 @SuppressWarnings("rawtypes") 087 public static final SortedMap EMPTY_SORTED_MAP = UnmodifiableSortedMap.unmodifiableSortedMap(new TreeMap<>()); 088 089 /** 090 * String used to indent the verbose and debug Map prints. 091 */ 092 private static final String INDENT_STRING = " "; 093 094 /** 095 * Applies the {@code getFunction} and returns its result if non-null, if null returns the result of applying the 096 * default function. 097 * 098 * @param <K> The key type. 099 * @param <R> The result type. 100 * @param map The map to query. 101 * @param key The key into the map. 102 * @param getFunction The get function. 103 * @param defaultFunction The function to provide a default value. 104 * @return The result of applying a function. 105 */ 106 private static <K, R> R applyDefaultFunction(final Map<? super K, ?> map, final K key, 107 final BiFunction<Map<? super K, ?>, K, R> getFunction, final Function<K, R> defaultFunction) { 108 return applyDefaultFunction(map, key, getFunction, defaultFunction, null); 109 } 110 111 /** 112 * Applies the {@code getFunction} and returns its result if non-null, if null returns the result of applying the 113 * default function. 114 * 115 * @param <K> The key type. 116 * @param <R> The result type. 117 * @param map The map to query. 118 * @param key The key into the map. 119 * @param getFunction The get function. 120 * @param defaultFunction The function to provide a default value. 121 * @param defaultValue The default value. 122 * @return The result of applying a function. 123 */ 124 private static <K, R> R applyDefaultFunction(final Map<? super K, ?> map, final K key, 125 final BiFunction<Map<? super K, ?>, K, R> getFunction, final Function<K, R> defaultFunction, 126 final R defaultValue) { 127 R value = map != null && getFunction != null ? getFunction.apply(map, key) : null; 128 if (value == null) { 129 value = defaultFunction != null ? defaultFunction.apply(key) : null; 130 } 131 return value != null ? value : defaultValue; 132 } 133 134 /** 135 * Applies the {@code getFunction} and returns its result if non-null, if null returns the {@code defaultValue}. 136 * 137 * @param <K> The key type. 138 * @param <R> The result type. 139 * @param map The map to query. 140 * @param key The key into the map. 141 * @param getFunction The get function. 142 * @param defaultValue The default value. 143 * @return The result of applying a function. 144 */ 145 private static <K, R> R applyDefaultValue(final Map<? super K, ?> map, final K key, 146 final BiFunction<Map<? super K, ?>, K, R> getFunction, final R defaultValue) { 147 final R value = map != null && getFunction != null ? getFunction.apply(map, key) : null; 148 return value == null ? defaultValue : value; 149 } 150 151 /** 152 * Prints the given map with nice line breaks. 153 * <p> 154 * This method prints a nicely formatted String describing the Map. Each map entry will be printed with key, value 155 * and value class name. When the value is a Map, recursive behavior occurs. 156 * </p> 157 * <p> 158 * This method is NOT thread-safe in any special way. You must manually synchronize on either this class or the 159 * stream as required. 160 * </p> 161 * 162 * @param out the stream to print to, must not be null 163 * @param label The label to be used, may be {@code null}. If {@code null}, the label is not output. It 164 * typically represents the name of the property in a bean or similar. 165 * @param map The map to print, may be {@code null}. If {@code null}, the text 'null' is output. 166 * @throws NullPointerException if the stream is {@code null} 167 */ 168 public static void debugPrint(final PrintStream out, final Object label, final Map<?, ?> map) { 169 verbosePrintInternal(out, label, map, new ArrayDeque<>(), true); 170 } 171 172 /** 173 * Returns an immutable empty map if the argument is {@code null}, or the argument itself otherwise. 174 * 175 * @param <K> the key type 176 * @param <V> the value type 177 * @param map the map, possibly {@code null} 178 * @return an empty map if the argument is {@code null} 179 */ 180 public static <K, V> Map<K, V> emptyIfNull(final Map<K, V> map) { 181 return map == null ? Collections.<K, V>emptyMap() : map; 182 } 183 184 /** 185 * Returns a fixed-sized map backed by the given map. Elements may not be added or removed from the returned map, 186 * but existing elements can be changed (for instance, via the {@link Map#put(Object,Object)} method). 187 * 188 * @param <K> the key type 189 * @param <V> the value type 190 * @param map the map whose size to fix, must not be null 191 * @return a fixed-size map backed by that map 192 * @throws NullPointerException if the Map is null 193 */ 194 public static <K, V> IterableMap<K, V> fixedSizeMap(final Map<K, V> map) { 195 return FixedSizeMap.fixedSizeMap(map); 196 } 197 198 /** 199 * Returns a fixed-sized sorted map backed by the given sorted map. Elements may not be added or removed from the 200 * returned map, but existing elements can be changed (for instance, via the {@link Map#put(Object,Object)} method). 201 * 202 * @param <K> the key type 203 * @param <V> the value type 204 * @param map the map whose size to fix, must not be null 205 * @return a fixed-size map backed by that map 206 * @throws NullPointerException if the SortedMap is null 207 */ 208 public static <K, V> SortedMap<K, V> fixedSizeSortedMap(final SortedMap<K, V> map) { 209 return FixedSizeSortedMap.fixedSizeSortedMap(map); 210 } 211 212 /** 213 * Gets a Boolean from a Map in a null-safe manner. 214 * <p> 215 * If the value is a {@code Boolean} it is returned directly. If the value is a {@code String} and it 216 * equals 'true' ignoring case then {@code true} is returned, otherwise {@code false}. If the value is a 217 * {@code Number} an integer zero value returns {@code false} and non-zero returns {@code true}. 218 * Otherwise, {@code null} is returned. 219 * </p> 220 * 221 * @param <K> the key type 222 * @param map the map to use 223 * @param key the key to look up 224 * @return the value in the Map as a Boolean, {@code null} if null map input 225 */ 226 public static <K> Boolean getBoolean(final Map<? super K, ?> map, final K key) { 227 if (map != null) { 228 final Object answer = map.get(key); 229 if (answer != null) { 230 if (answer instanceof Boolean) { 231 return (Boolean) answer; 232 } 233 if (answer instanceof String) { 234 return Boolean.valueOf((String) answer); 235 } 236 if (answer instanceof Number) { 237 final Number n = (Number) answer; 238 return n.intValue() != 0 ? Boolean.TRUE : Boolean.FALSE; 239 } 240 } 241 } 242 return null; 243 } 244 245 /** 246 * Looks up the given key in the given map, converting the result into a boolean, using the default value if the 247 * conversion fails. 248 * 249 * @param <K> the key type 250 * @param map the map whose value to look up 251 * @param key the key of the value to look up in that map 252 * @param defaultValue what to return if the value is null or if the conversion fails 253 * @return the value in the map as a boolean, or defaultValue if the original value is null, the map is null or the 254 * boolean conversion fails 255 */ 256 public static <K> Boolean getBoolean(final Map<? super K, ?> map, final K key, final Boolean defaultValue) { 257 return applyDefaultValue(map, key, MapUtils::getBoolean, defaultValue); 258 } 259 260 /** 261 * Looks up the given key in the given map, converting the result into a boolean, using the defaultFunction to 262 * produce the default value if the conversion fails. 263 * 264 * @param <K> the key type 265 * @param map the map whose value to look up 266 * @param key the key of the value to look up in that map 267 * @param defaultFunction what to produce the default value if the value is null or if the conversion fails 268 * @return the value in the map as a boolean, or defaultValue produced by the defaultFunction if the original value 269 * is null, the map is null or the boolean conversion fails 270 * @since 4.5 271 */ 272 public static <K> Boolean getBoolean(final Map<? super K, ?> map, final K key, 273 final Function<K, Boolean> defaultFunction) { 274 return applyDefaultFunction(map, key, MapUtils::getBoolean, defaultFunction); 275 } 276 277 /** 278 * Gets a boolean from a Map in a null-safe manner. 279 * <p> 280 * If the value is a {@code Boolean} its value is returned. If the value is a {@code String} and it equals 281 * 'true' ignoring case then {@code true} is returned, otherwise {@code false}. If the value is a 282 * {@code Number} an integer zero value returns {@code false} and non-zero returns {@code true}. 283 * Otherwise, {@code false} is returned. 284 * </p> 285 * 286 * @param <K> the key type 287 * @param map the map to use 288 * @param key the key to look up 289 * @return the value in the Map as a Boolean, {@code false} if null map input 290 */ 291 public static <K> boolean getBooleanValue(final Map<? super K, ?> map, final K key) { 292 return Boolean.TRUE.equals(getBoolean(map, key)); 293 } 294 295 /** 296 * Gets a boolean from a Map in a null-safe manner, using the default value if the conversion fails. 297 * <p> 298 * If the value is a {@code Boolean} its value is returned. If the value is a {@code String} and it equals 299 * 'true' ignoring case then {@code true} is returned, otherwise {@code false}. If the value is a 300 * {@code Number} an integer zero value returns {@code false} and non-zero returns {@code true}. 301 * Otherwise, {@code defaultValue} is returned. 302 * </p> 303 * 304 * @param <K> the key type 305 * @param map the map to use 306 * @param key the key to look up 307 * @param defaultValue return if the value is null or if the conversion fails 308 * @return the value in the Map as a Boolean, {@code defaultValue} if null map input 309 */ 310 public static <K> boolean getBooleanValue(final Map<? super K, ?> map, final K key, final boolean defaultValue) { 311 return applyDefaultValue(map, key, MapUtils::getBoolean, defaultValue).booleanValue(); 312 } 313 314 /** 315 * Gets a boolean from a Map in a null-safe manner, using the default value produced by the defaultFunction if the 316 * conversion fails. 317 * <p> 318 * If the value is a {@code Boolean} its value is returned. If the value is a {@code String} and it equals 319 * 'true' ignoring case then {@code true} is returned, otherwise {@code false}. If the value is a 320 * {@code Number} an integer zero value returns {@code false} and non-zero returns {@code true}. 321 * Otherwise, defaultValue produced by the {@code defaultFunction} is returned. 322 * </p> 323 * 324 * @param <K> the key type 325 * @param map the map to use 326 * @param key the key to look up 327 * @param defaultFunction produce the default value to return if the value is null or if the conversion fails 328 * @return the value in the Map as a Boolean, default value produced by the {@code defaultFunction} if null map 329 * input 330 * @since 4.5 331 */ 332 public static <K> boolean getBooleanValue(final Map<? super K, ?> map, final K key, 333 final Function<K, Boolean> defaultFunction) { 334 return applyDefaultFunction(map, key, MapUtils::getBoolean, defaultFunction, false).booleanValue(); 335 } 336 337 /** 338 * Gets a Byte from a Map in a null-safe manner. 339 * <p> 340 * The Byte is obtained from the results of {@link #getNumber(Map,Object)}. 341 * </p> 342 * 343 * @param <K> the key type 344 * @param map the map to use 345 * @param key the key to look up 346 * @return the value in the Map as a Byte, {@code null} if null map input 347 */ 348 public static <K> Byte getByte(final Map<? super K, ?> map, final K key) { 349 final Number answer = getNumber(map, key); 350 if (answer == null) { 351 return null; 352 } 353 if (answer instanceof Byte) { 354 return (Byte) answer; 355 } 356 return Byte.valueOf(answer.byteValue()); 357 } 358 359 /** 360 * Looks up the given key in the given map, converting the result into a byte, using the default value if the 361 * conversion fails. 362 * 363 * @param <K> the key type 364 * @param map the map whose value to look up 365 * @param key the key of the value to look up in that map 366 * @param defaultValue what to return if the value is null or if the conversion fails 367 * @return the value in the map as a number, or defaultValue if the original value is null, the map is null or the 368 * number conversion fails 369 */ 370 public static <K> Byte getByte(final Map<? super K, ?> map, final K key, final Byte defaultValue) { 371 return applyDefaultValue(map, key, MapUtils::getByte, defaultValue); 372 } 373 374 /** 375 * Looks up the given key in the given map, converting the result into a byte, using the defaultFunction to produce 376 * the default value if the conversion fails. 377 * 378 * @param <K> the key type 379 * @param map the map whose value to look up 380 * @param key the key of the value to look up in that map 381 * @param defaultFunction what to produce the default value if the value is null or if the conversion fails 382 * @return the value in the map as a number, or defaultValue produced by the defaultFunction if the original value 383 * is null, the map is null or the number conversion fails 384 * @since 4.5 385 */ 386 public static <K> Byte getByte(final Map<? super K, ?> map, final K key, final Function<K, Byte> defaultFunction) { 387 return applyDefaultFunction(map, key, MapUtils::getByte, defaultFunction); 388 } 389 390 /** 391 * Gets a byte from a Map in a null-safe manner. 392 * <p> 393 * The byte is obtained from the results of {@link #getNumber(Map,Object)}. 394 * </p> 395 * 396 * @param <K> the key type 397 * @param map the map to use 398 * @param key the key to look up 399 * @return the value in the Map as a byte, {@code 0} if null map input 400 */ 401 public static <K> byte getByteValue(final Map<? super K, ?> map, final K key) { 402 return applyDefaultValue(map, key, MapUtils::getByte, 0).byteValue(); 403 } 404 405 /** 406 * Gets a byte from a Map in a null-safe manner, using the default value if the conversion fails. 407 * <p> 408 * The byte is obtained from the results of {@link #getNumber(Map,Object)}. 409 * </p> 410 * 411 * @param <K> the key type 412 * @param map the map to use 413 * @param key the key to look up 414 * @param defaultValue return if the value is null or if the conversion fails 415 * @return the value in the Map as a byte, {@code defaultValue} if null map input 416 */ 417 public static <K> byte getByteValue(final Map<? super K, ?> map, final K key, final byte defaultValue) { 418 return applyDefaultValue(map, key, MapUtils::getByte, defaultValue).byteValue(); 419 } 420 421 /** 422 * Gets a byte from a Map in a null-safe manner, using the default value produced by the defaultFunction if the 423 * conversion fails. 424 * <p> 425 * The byte is obtained from the results of {@link #getNumber(Map,Object)}. 426 * </p> 427 * 428 * @param <K> the key type 429 * @param map the map to use 430 * @param key the key to look up 431 * @param defaultFunction produce the default value to return if the value is null or if the conversion fails 432 * @return the value in the Map as a byte, default value produced by the {@code defaultFunction} if null map 433 * input 434 * @since 4.5 435 */ 436 public static <K> byte getByteValue(final Map<? super K, ?> map, final K key, 437 final Function<K, Byte> defaultFunction) { 438 return applyDefaultFunction(map, key, MapUtils::getByte, defaultFunction, (byte) 0).byteValue(); 439 } 440 441 /** 442 * Gets a Double from a Map in a null-safe manner. 443 * <p> 444 * The Double is obtained from the results of {@link #getNumber(Map,Object)}. 445 * </p> 446 * 447 * @param <K> the key type 448 * @param map the map to use 449 * @param key the key to look up 450 * @return the value in the Map as a Double, {@code null} if null map input 451 */ 452 public static <K> Double getDouble(final Map<? super K, ?> map, final K key) { 453 final Number answer = getNumber(map, key); 454 if (answer == null) { 455 return null; 456 } 457 if (answer instanceof Double) { 458 return (Double) answer; 459 } 460 return Double.valueOf(answer.doubleValue()); 461 } 462 463 /** 464 * Looks up the given key in the given map, converting the result into a double, using the default value if the 465 * conversion fails. 466 * 467 * @param <K> the key type 468 * @param map the map whose value to look up 469 * @param key the key of the value to look up in that map 470 * @param defaultValue what to return if the value is null or if the conversion fails 471 * @return the value in the map as a number, or defaultValue if the original value is null, the map is null or the 472 * number conversion fails 473 */ 474 public static <K> Double getDouble(final Map<? super K, ?> map, final K key, final Double defaultValue) { 475 return applyDefaultValue(map, key, MapUtils::getDouble, defaultValue); 476 } 477 478 /** 479 * Looks up the given key in the given map, converting the result into a double, using the defaultFunction to 480 * produce the default value if the conversion fails. 481 * 482 * @param <K> the key type 483 * @param map the map whose value to look up 484 * @param key the key of the value to look up in that map 485 * @param defaultFunction what to produce the default value if the value is null or if the conversion fails 486 * @return the value in the map as a number, or defaultValue produced by the defaultFunction if the original value 487 * is null, the map is null or the number conversion fails 488 * @since 4.5 489 */ 490 public static <K> Double getDouble(final Map<? super K, ?> map, final K key, 491 final Function<K, Double> defaultFunction) { 492 return applyDefaultFunction(map, key, MapUtils::getDouble, defaultFunction); 493 } 494 495 /** 496 * Gets a double from a Map in a null-safe manner. 497 * <p> 498 * The double is obtained from the results of {@link #getNumber(Map,Object)}. 499 * </p> 500 * 501 * @param <K> the key type 502 * @param map the map to use 503 * @param key the key to look up 504 * @return the value in the Map as a double, {@code 0.0} if null map input 505 */ 506 public static <K> double getDoubleValue(final Map<? super K, ?> map, final K key) { 507 return applyDefaultValue(map, key, MapUtils::getDouble, 0d).doubleValue(); 508 } 509 510 /** 511 * Gets a double from a Map in a null-safe manner, using the default value if the conversion fails. 512 * <p> 513 * The double is obtained from the results of {@link #getNumber(Map,Object)}. 514 * </p> 515 * 516 * @param <K> the key type 517 * @param map the map to use 518 * @param key the key to look up 519 * @param defaultValue return if the value is null or if the conversion fails 520 * @return the value in the Map as a double, {@code defaultValue} if null map input 521 */ 522 public static <K> double getDoubleValue(final Map<? super K, ?> map, final K key, final double defaultValue) { 523 return applyDefaultValue(map, key, MapUtils::getDouble, defaultValue).doubleValue(); 524 } 525 526 /** 527 * Gets a double from a Map in a null-safe manner, using the default value produced by the defaultFunction if the 528 * conversion fails. 529 * <p> 530 * The double is obtained from the results of {@link #getNumber(Map,Object)}. 531 * </p> 532 * 533 * @param <K> the key type 534 * @param map the map to use 535 * @param key the key to look up 536 * @param defaultFunction produce the default value to return if the value is null or if the conversion fails 537 * @return the value in the Map as a double, default value produced by the {@code defaultFunction} if null map 538 * input 539 * @since 4.5 540 */ 541 public static <K> double getDoubleValue(final Map<? super K, ?> map, final K key, 542 final Function<K, Double> defaultFunction) { 543 return applyDefaultFunction(map, key, MapUtils::getDouble, defaultFunction, 0d).doubleValue(); 544 } 545 546 /** 547 * Gets a Float from a Map in a null-safe manner. 548 * <p> 549 * The Float is obtained from the results of {@link #getNumber(Map,Object)}. 550 * </p> 551 * 552 * @param <K> the key type 553 * @param map the map to use 554 * @param key the key to look up 555 * @return the value in the Map as a Float, {@code null} if null map input 556 */ 557 public static <K> Float getFloat(final Map<? super K, ?> map, final K key) { 558 final Number answer = getNumber(map, key); 559 if (answer == null) { 560 return null; 561 } 562 if (answer instanceof Float) { 563 return (Float) answer; 564 } 565 return Float.valueOf(answer.floatValue()); 566 } 567 568 /** 569 * Looks up the given key in the given map, converting the result into a float, using the default value if the 570 * conversion fails. 571 * 572 * @param <K> the key type 573 * @param map the map whose value to look up 574 * @param key the key of the value to look up in that map 575 * @param defaultValue what to return if the value is null or if the conversion fails 576 * @return the value in the map as a number, or defaultValue if the original value is null, the map is null or the 577 * number conversion fails 578 */ 579 public static <K> Float getFloat(final Map<? super K, ?> map, final K key, final Float defaultValue) { 580 return applyDefaultValue(map, key, MapUtils::getFloat, defaultValue); 581 } 582 583 /** 584 * Looks up the given key in the given map, converting the result into a float, using the defaultFunction to produce 585 * the default value if the conversion fails. 586 * 587 * @param <K> the key type 588 * @param map the map whose value to look up 589 * @param key the key of the value to look up in that map 590 * @param defaultFunction what to produce the default value if the value is null or if the conversion fails 591 * @return the value in the map as a number, or defaultValue produced by the defaultFunction if the original value 592 * is null, the map is null or the number conversion fails 593 * @since 4.5 594 */ 595 public static <K> Float getFloat(final Map<? super K, ?> map, final K key, 596 final Function<K, Float> defaultFunction) { 597 return applyDefaultFunction(map, key, MapUtils::getFloat, defaultFunction); 598 } 599 600 /** 601 * Gets a float from a Map in a null-safe manner. 602 * <p> 603 * The float is obtained from the results of {@link #getNumber(Map,Object)}. 604 * </p> 605 * 606 * @param <K> the key type 607 * @param map the map to use 608 * @param key the key to look up 609 * @return the value in the Map as a float, {@code 0.0F} if null map input 610 */ 611 public static <K> float getFloatValue(final Map<? super K, ?> map, final K key) { 612 return applyDefaultValue(map, key, MapUtils::getFloat, 0f).floatValue(); 613 } 614 615 /** 616 * Gets a float from a Map in a null-safe manner, using the default value if the conversion fails. 617 * <p> 618 * The float is obtained from the results of {@link #getNumber(Map,Object)}. 619 * </p> 620 * 621 * @param <K> the key type 622 * @param map the map to use 623 * @param key the key to look up 624 * @param defaultValue return if the value is null or if the conversion fails 625 * @return the value in the Map as a float, {@code defaultValue} if null map input 626 */ 627 public static <K> float getFloatValue(final Map<? super K, ?> map, final K key, final float defaultValue) { 628 return applyDefaultValue(map, key, MapUtils::getFloat, defaultValue).floatValue(); 629 } 630 631 /** 632 * Gets a float from a Map in a null-safe manner, using the default value produced by the defaultFunction if the 633 * conversion fails. 634 * <p> 635 * The float is obtained from the results of {@link #getNumber(Map,Object)}. 636 * </p> 637 * 638 * @param <K> the key type 639 * @param map the map to use 640 * @param key the key to look up 641 * @param defaultFunction produce the default value to return if the value is null or if the conversion fails 642 * @return the value in the Map as a float, default value produced by the {@code defaultFunction} if null map 643 * input 644 * @since 4.5 645 */ 646 public static <K> float getFloatValue(final Map<? super K, ?> map, final K key, 647 final Function<K, Float> defaultFunction) { 648 return applyDefaultFunction(map, key, MapUtils::getFloat, defaultFunction, 0f).floatValue(); 649 } 650 651 /** 652 * Gets an Integer from a Map in a null-safe manner. 653 * <p> 654 * The Integer is obtained from the results of {@link #getNumber(Map,Object)}. 655 * </p> 656 * 657 * @param <K> the key type 658 * @param map the map to use 659 * @param key the key to look up 660 * @return the value in the Map as an Integer, {@code null} if null map input 661 */ 662 public static <K> Integer getInteger(final Map<? super K, ?> map, final K key) { 663 final Number answer = getNumber(map, key); 664 if (answer == null) { 665 return null; 666 } 667 if (answer instanceof Integer) { 668 return (Integer) answer; 669 } 670 return Integer.valueOf(answer.intValue()); 671 } 672 673 /** 674 * Looks up the given key in the given map, converting the result into an integer, using the defaultFunction to 675 * produce the default value if the conversion fails. 676 * 677 * @param <K> the key type 678 * @param map the map whose value to look up 679 * @param key the key of the value to look up in that map 680 * @param defaultFunction what to produce the default value if the value is null or if the conversion fails 681 * @return the value in the map as a number, or defaultValue produced by the defaultFunction if the original value 682 * is null, the map is null or the number conversion fails 683 * @since 4.5 684 */ 685 public static <K> Integer getInteger(final Map<? super K, ?> map, final K key, 686 final Function<K, Integer> defaultFunction) { 687 return applyDefaultFunction(map, key, MapUtils::getInteger, defaultFunction); 688 } 689 690 /** 691 * Looks up the given key in the given map, converting the result into an integer, using the default value if the 692 * conversion fails. 693 * 694 * @param <K> the key type 695 * @param map the map whose value to look up 696 * @param key the key of the value to look up in that map 697 * @param defaultValue what to return if the value is null or if the conversion fails 698 * @return the value in the map as a number, or defaultValue if the original value is null, the map is null or the 699 * number conversion fails 700 */ 701 public static <K> Integer getInteger(final Map<? super K, ?> map, final K key, final Integer defaultValue) { 702 return applyDefaultValue(map, key, MapUtils::getInteger, defaultValue); 703 } 704 705 /** 706 * Gets an int from a Map in a null-safe manner. 707 * <p> 708 * The int is obtained from the results of {@link #getNumber(Map,Object)}. 709 * </p> 710 * 711 * @param <K> the key type 712 * @param map the map to use 713 * @param key the key to look up 714 * @return the value in the Map as an int, {@code 0} if null map input 715 */ 716 public static <K> int getIntValue(final Map<? super K, ?> map, final K key) { 717 return applyDefaultValue(map, key, MapUtils::getInteger, 0).intValue(); 718 } 719 720 /** 721 * Gets an int from a Map in a null-safe manner, using the default value produced by the defaultFunction if the 722 * conversion fails. 723 * <p> 724 * The int is obtained from the results of {@link #getNumber(Map,Object)}. 725 * </p> 726 * 727 * @param <K> the key type 728 * @param map the map to use 729 * @param key the key to look up 730 * @param defaultFunction produce the default value to return if the value is null or if the conversion fails 731 * @return the value in the Map as an int, default value produced by the {@code defaultFunction} if null map 732 * input 733 * @since 4.5 734 */ 735 public static <K> int getIntValue(final Map<? super K, ?> map, final K key, 736 final Function<K, Integer> defaultFunction) { 737 return applyDefaultFunction(map, key, MapUtils::getInteger, defaultFunction, 0).byteValue(); 738 } 739 740 /** 741 * Gets an int from a Map in a null-safe manner, using the default value if the conversion fails. 742 * <p> 743 * The int is obtained from the results of {@link #getNumber(Map,Object)}. 744 * </p> 745 * 746 * @param <K> the key type 747 * @param map the map to use 748 * @param key the key to look up 749 * @param defaultValue return if the value is null or if the conversion fails 750 * @return the value in the Map as an int, {@code defaultValue} if null map input 751 */ 752 public static <K> int getIntValue(final Map<? super K, ?> map, final K key, final int defaultValue) { 753 return applyDefaultValue(map, key, MapUtils::getInteger, defaultValue).intValue(); 754 } 755 756 /** 757 * Gets a Long from a Map in a null-safe manner. 758 * <p> 759 * The Long is obtained from the results of {@link #getNumber(Map,Object)}. 760 * </p> 761 * 762 * @param <K> the key type 763 * @param map the map to use 764 * @param key the key to look up 765 * @return the value in the Map as a Long, {@code null} if null map input 766 */ 767 public static <K> Long getLong(final Map<? super K, ?> map, final K key) { 768 final Number answer = getNumber(map, key); 769 if (answer == null) { 770 return null; 771 } 772 if (answer instanceof Long) { 773 return (Long) answer; 774 } 775 return Long.valueOf(answer.longValue()); 776 } 777 778 /** 779 * Looks up the given key in the given map, converting the result into a Long, using the defaultFunction to produce 780 * the default value if the conversion fails. 781 * 782 * @param <K> the key type 783 * @param map the map whose value to look up 784 * @param key the key of the value to look up in that map 785 * @param defaultFunction what to produce the default value if the value is null or if the conversion fails 786 * @return the value in the map as a number, or defaultValue produced by the defaultFunction if the original value 787 * is null, the map is null or the number conversion fails 788 * @since 4.5 789 */ 790 public static <K> Long getLong(final Map<? super K, ?> map, final K key, final Function<K, Long> defaultFunction) { 791 return applyDefaultFunction(map, key, MapUtils::getLong, defaultFunction); 792 } 793 794 /** 795 * Looks up the given key in the given map, converting the result into a long, using the default value if the 796 * conversion fails. 797 * 798 * @param <K> the key type 799 * @param map the map whose value to look up 800 * @param key the key of the value to look up in that map 801 * @param defaultValue what to return if the value is null or if the conversion fails 802 * @return the value in the map as a number, or defaultValue if the original value is null, the map is null or the 803 * number conversion fails 804 */ 805 public static <K> Long getLong(final Map<? super K, ?> map, final K key, final Long defaultValue) { 806 return applyDefaultValue(map, key, MapUtils::getLong, defaultValue); 807 } 808 809 /** 810 * Gets a long from a Map in a null-safe manner. 811 * <p> 812 * The long is obtained from the results of {@link #getNumber(Map,Object)}. 813 * </p> 814 * 815 * @param <K> the key type 816 * @param map the map to use 817 * @param key the key to look up 818 * @return the value in the Map as a long, {@code 0L} if null map input 819 */ 820 public static <K> long getLongValue(final Map<? super K, ?> map, final K key) { 821 return applyDefaultValue(map, key, MapUtils::getLong, 0L).longValue(); 822 } 823 824 /** 825 * Gets a long from a Map in a null-safe manner, using the default value produced by the defaultFunction if the 826 * conversion fails. 827 * <p> 828 * The long is obtained from the results of {@link #getNumber(Map,Object)}. 829 * </p> 830 * 831 * @param <K> the key type 832 * @param map the map to use 833 * @param key the key to look up 834 * @param defaultFunction produce the default value to return if the value is null or if the conversion fails 835 * @return the value in the Map as a long, default value produced by the {@code defaultFunction} if null map 836 * input 837 * @since 4.5 838 */ 839 public static <K> long getLongValue(final Map<? super K, ?> map, final K key, 840 final Function<K, Long> defaultFunction) { 841 return applyDefaultFunction(map, key, MapUtils::getLong, defaultFunction, 0L).byteValue(); 842 } 843 844 /** 845 * Gets a long from a Map in a null-safe manner, using the default value if the conversion fails. 846 * <p> 847 * The long is obtained from the results of {@link #getNumber(Map,Object)}. 848 * </p> 849 * 850 * @param <K> the key type 851 * @param map the map to use 852 * @param key the key to look up 853 * @param defaultValue return if the value is null or if the conversion fails 854 * @return the value in the Map as a long, {@code defaultValue} if null map input 855 */ 856 public static <K> long getLongValue(final Map<? super K, ?> map, final K key, final long defaultValue) { 857 return applyDefaultValue(map, key, MapUtils::getLong, defaultValue).longValue(); 858 } 859 860 /** 861 * Gets a Map from a Map in a null-safe manner. 862 * <p> 863 * If the value returned from the specified map is not a Map then {@code null} is returned. 864 * </p> 865 * 866 * @param <K> the key type 867 * @param map the map to use 868 * @param key the key to look up 869 * @return the value in the Map as a Map, {@code null} if null map input 870 */ 871 public static <K> Map<?, ?> getMap(final Map<? super K, ?> map, final K key) { 872 if (map != null) { 873 final Object answer = map.get(key); 874 if (answer instanceof Map) { 875 return (Map<?, ?>) answer; 876 } 877 } 878 return null; 879 } 880 881 /** 882 * Looks up the given key in the given map, converting the result into a map, using the defaultFunction to produce 883 * the default value if the conversion fails. 884 * 885 * @param <K> the key type 886 * @param map the map whose value to look up 887 * @param key the key of the value to look up in that map 888 * @param defaultFunction what to produce the default value if the value is null or if the conversion fails 889 * @return the value in the map as a number, or defaultValue produced by the defaultFunction if the original value 890 * is null, the map is null or the map conversion fails 891 * @since 4.5 892 */ 893 public static <K> Map<?, ?> getMap(final Map<? super K, ?> map, final K key, 894 final Function<K, Map<?, ?>> defaultFunction) { 895 return applyDefaultFunction(map, key, MapUtils::getMap, defaultFunction); 896 } 897 898 /** 899 * Looks up the given key in the given map, converting the result into a map, using the default value if the 900 * conversion fails. 901 * 902 * @param <K> the key type 903 * @param map the map whose value to look up 904 * @param key the key of the value to look up in that map 905 * @param defaultValue what to return if the value is null or if the conversion fails 906 * @return the value in the map as a number, or defaultValue if the original value is null, the map is null or the 907 * map conversion fails 908 */ 909 public static <K> Map<?, ?> getMap(final Map<? super K, ?> map, final K key, final Map<?, ?> defaultValue) { 910 return applyDefaultValue(map, key, MapUtils::getMap, defaultValue); 911 } 912 913 /** 914 * Gets a Number from a Map in a null-safe manner. 915 * <p> 916 * If the value is a {@code Number} it is returned directly. If the value is a {@code String} it is 917 * converted using {@link NumberFormat#parse(String)} on the system default formatter returning {@code null} if 918 * the conversion fails. Otherwise, {@code null} is returned. 919 * </p> 920 * 921 * @param <K> the key type 922 * @param map the map to use 923 * @param key the key to look up 924 * @return the value in the Map as a Number, {@code null} if null map input 925 */ 926 public static <K> Number getNumber(final Map<? super K, ?> map, final K key) { 927 if (map != null) { 928 final Object answer = map.get(key); 929 if (answer != null) { 930 if (answer instanceof Number) { 931 return (Number) answer; 932 } 933 if (answer instanceof String) { 934 try { 935 final String text = (String) answer; 936 return NumberFormat.getInstance().parse(text); 937 } catch (final ParseException e) { // NOPMD 938 // failure means null is returned 939 } 940 } 941 } 942 } 943 return null; 944 } 945 946 /** 947 * Looks up the given key in the given map, converting the result into a number, using the defaultFunction to 948 * produce the default value if the conversion fails. 949 * 950 * @param <K> the key type 951 * @param map the map whose value to look up 952 * @param key the key of the value to look up in that map 953 * @param defaultFunction what to produce the default value if the value is null or if the conversion fails 954 * @return the value in the map as a number, or defaultValue produced by the defaultFunction if the original value 955 * is null, the map is null or the number conversion fails 956 * @since 4.5 957 */ 958 public static <K> Number getNumber(final Map<? super K, ?> map, final K key, 959 final Function<K, Number> defaultFunction) { 960 return applyDefaultFunction(map, key, MapUtils::getNumber, defaultFunction); 961 } 962 963 /** 964 * Looks up the given key in the given map, converting the result into a number, using the default value if the 965 * conversion fails. 966 * 967 * @param <K> the key type 968 * @param map the map whose value to look up 969 * @param key the key of the value to look up in that map 970 * @param defaultValue what to return if the value is null or if the conversion fails 971 * @return the value in the map as a number, or defaultValue if the original value is null, the map is null or the 972 * number conversion fails 973 */ 974 public static <K> Number getNumber(final Map<? super K, ?> map, final K key, final Number defaultValue) { 975 return applyDefaultValue(map, key, MapUtils::getNumber, defaultValue); 976 } 977 978 /** 979 * Gets from a Map in a null-safe manner. 980 * 981 * @param <K> the key type 982 * @param <V> the value type 983 * @param map the map to use 984 * @param key the key to look up 985 * @return the value in the Map, {@code null} if null map input 986 */ 987 public static <K, V> V getObject(final Map<? super K, V> map, final K key) { 988 if (map != null) { 989 return map.get(key); 990 } 991 return null; 992 } 993 994 /** 995 * Looks up the given key in the given map, converting null into the given default value. 996 * 997 * @param <K> the key type 998 * @param <V> the value type 999 * @param map the map whose value to look up 1000 * @param key the key of the value to look up in that map 1001 * @param defaultValue what to return if the value is null 1002 * @return the value in the map, or defaultValue if the original value is null or the map is null 1003 */ 1004 public static <K, V> V getObject(final Map<K, V> map, final K key, final V defaultValue) { 1005 if (map != null) { 1006 final V answer = map.get(key); 1007 if (answer != null) { 1008 return answer; 1009 } 1010 } 1011 return defaultValue; 1012 } 1013 1014 /** 1015 * Gets a Short from a Map in a null-safe manner. 1016 * <p> 1017 * The Short is obtained from the results of {@link #getNumber(Map,Object)}. 1018 * </p> 1019 * 1020 * @param <K> the key type 1021 * @param map the map to use 1022 * @param key the key to look up 1023 * @return the value in the Map as a Short, {@code null} if null map input 1024 */ 1025 public static <K> Short getShort(final Map<? super K, ?> map, final K key) { 1026 final Number answer = getNumber(map, key); 1027 if (answer == null) { 1028 return null; 1029 } 1030 if (answer instanceof Short) { 1031 return (Short) answer; 1032 } 1033 return Short.valueOf(answer.shortValue()); 1034 } 1035 1036 /** 1037 * Looks up the given key in the given map, converting the result into a short, using the defaultFunction to produce 1038 * the default value if the conversion fails. 1039 * 1040 * @param <K> the key type 1041 * @param map the map whose value to look up 1042 * @param key the key of the value to look up in that map 1043 * @param defaultFunction what to produce the default value if the value is null or if the conversion fails 1044 * @return the value in the map as a number, or defaultValue produced by the defaultFunction if the original value 1045 * is null, the map is null or the number conversion fails 1046 * @since 4.5 1047 */ 1048 public static <K> Short getShort(final Map<? super K, ?> map, final K key, 1049 final Function<K, Short> defaultFunction) { 1050 return applyDefaultFunction(map, key, MapUtils::getShort, defaultFunction); 1051 } 1052 1053 /** 1054 * Looks up the given key in the given map, converting the result into a short, using the default value if the 1055 * conversion fails. 1056 * 1057 * @param <K> the key type 1058 * @param map the map whose value to look up 1059 * @param key the key of the value to look up in that map 1060 * @param defaultValue what to return if the value is null or if the conversion fails 1061 * @return the value in the map as a number, or defaultValue if the original value is null, the map is null or the 1062 * number conversion fails 1063 */ 1064 public static <K> Short getShort(final Map<? super K, ?> map, final K key, final Short defaultValue) { 1065 return applyDefaultValue(map, key, MapUtils::getShort, defaultValue); 1066 } 1067 1068 /** 1069 * Gets a short from a Map in a null-safe manner. 1070 * <p> 1071 * The short is obtained from the results of {@link #getNumber(Map,Object)}. 1072 * </p> 1073 * 1074 * @param <K> the key type 1075 * @param map the map to use 1076 * @param key the key to look up 1077 * @return the value in the Map as a short, {@code 0} if null map input 1078 */ 1079 public static <K> short getShortValue(final Map<? super K, ?> map, final K key) { 1080 return applyDefaultValue(map, key, MapUtils::getShort, 0).shortValue(); 1081 } 1082 1083 /** 1084 * Gets a short from a Map in a null-safe manner, using the default value produced by the defaultFunction if the 1085 * conversion fails. 1086 * <p> 1087 * The short is obtained from the results of {@link #getNumber(Map,Object)}. 1088 * </p> 1089 * 1090 * @param <K> the key type 1091 * @param map the map to use 1092 * @param key the key to look up 1093 * @param defaultFunction produce the default value to return if the value is null or if the conversion fails 1094 * @return the value in the Map as a short, default value produced by the {@code defaultFunction} if null map 1095 * input 1096 * @since 4.5 1097 */ 1098 public static <K> short getShortValue(final Map<? super K, ?> map, final K key, 1099 final Function<K, Short> defaultFunction) { 1100 return applyDefaultFunction(map, key, MapUtils::getShort, defaultFunction, (short) 0).shortValue(); 1101 } 1102 1103 /** 1104 * Gets a short from a Map in a null-safe manner, using the default value if the conversion fails. 1105 * <p> 1106 * The short is obtained from the results of {@link #getNumber(Map,Object)}. 1107 * </p> 1108 * 1109 * @param <K> the key type 1110 * @param map the map to use 1111 * @param key the key to look up 1112 * @param defaultValue return if the value is null or if the conversion fails 1113 * @return the value in the Map as a short, {@code defaultValue} if null map input 1114 */ 1115 public static <K> short getShortValue(final Map<? super K, ?> map, final K key, final short defaultValue) { 1116 return applyDefaultValue(map, key, MapUtils::getShort, defaultValue).shortValue(); 1117 } 1118 1119 /** 1120 * Gets a String from a Map in a null-safe manner. 1121 * <p> 1122 * The String is obtained via {@code toString}. 1123 * </p> 1124 * 1125 * @param <K> the key type 1126 * @param map the map to use 1127 * @param key the key to look up 1128 * @return the value in the Map as a String, {@code null} if null map input 1129 */ 1130 public static <K> String getString(final Map<? super K, ?> map, final K key) { 1131 if (map != null) { 1132 final Object answer = map.get(key); 1133 if (answer != null) { 1134 return answer.toString(); 1135 } 1136 } 1137 return null; 1138 } 1139 1140 /** 1141 * Looks up the given key in the given map, converting the result into a string, using the defaultFunction to 1142 * produce the default value if the conversion fails. 1143 * 1144 * @param <K> the key type 1145 * @param map the map whose value to look up 1146 * @param key the key of the value to look up in that map 1147 * @param defaultFunction what to produce the default value if the value is null or if the conversion fails 1148 * @return the value in the map as a string, or defaultValue produced by the defaultFunction if the original value 1149 * is null, the map is null or the string conversion fails 1150 * @since 4.5 1151 */ 1152 public static <K> String getString(final Map<? super K, ?> map, final K key, 1153 final Function<K, String> defaultFunction) { 1154 return applyDefaultFunction(map, key, MapUtils::getString, defaultFunction); 1155 } 1156 1157 /** 1158 * Looks up the given key in the given map, converting the result into a string, using the default value if the 1159 * conversion fails. 1160 * 1161 * @param <K> the key type 1162 * @param map the map whose value to look up 1163 * @param key the key of the value to look up in that map 1164 * @param defaultValue what to return if the value is null or if the conversion fails 1165 * @return the value in the map as a string, or defaultValue if the original value is null, the map is null or the 1166 * string conversion fails 1167 */ 1168 public static <K> String getString(final Map<? super K, ?> map, final K key, final String defaultValue) { 1169 return applyDefaultValue(map, key, MapUtils::getString, defaultValue); 1170 } 1171 1172 /** 1173 * Inverts the supplied map returning a new HashMap such that the keys of the input are swapped with the values. 1174 * <p> 1175 * This operation assumes that the inverse mapping is well defined. If the input map had multiple entries with the 1176 * same value mapped to different keys, the returned map will map one of those keys to the value, but the exact key 1177 * which will be mapped is undefined. 1178 * </p> 1179 * 1180 * @param <K> the key type 1181 * @param <V> the value type 1182 * @param map the map to invert, must not be null 1183 * @return a new HashMap containing the inverted data 1184 * @throws NullPointerException if the map is null 1185 */ 1186 public static <K, V> Map<V, K> invertMap(final Map<K, V> map) { 1187 Objects.requireNonNull(map, "map"); 1188 final Map<V, K> out = new HashMap<>(map.size()); 1189 for (final Entry<K, V> entry : map.entrySet()) { 1190 out.put(entry.getValue(), entry.getKey()); 1191 } 1192 return out; 1193 } 1194 1195 /** 1196 * Null-safe check if the specified map is empty. 1197 * <p> 1198 * Null returns true. 1199 * </p> 1200 * 1201 * @param map the map to check, may be null 1202 * @return true if empty or null 1203 * @since 3.2 1204 */ 1205 public static boolean isEmpty(final Map<?, ?> map) { 1206 return map == null || map.isEmpty(); 1207 } 1208 1209 /** 1210 * Null-safe check if the specified map is not empty. 1211 * <p> 1212 * Null returns false. 1213 * </p> 1214 * 1215 * @param map the map to check, may be null 1216 * @return true if non-null and non-empty 1217 * @since 3.2 1218 */ 1219 public static boolean isNotEmpty(final Map<?, ?> map) { 1220 return !isEmpty(map); 1221 } 1222 1223 /** 1224 * Gets the specified {@link Map} as an {@link IterableMap}. 1225 * 1226 * @param <K> the key type 1227 * @param <V> the value type 1228 * @param map to wrap if necessary. 1229 * @return IterableMap<K, V> 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}<K, V> 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}