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