1 /* 2 3 dsh-collect Collection and map utility classes. 4 Copyright (c) 2008-2013 held jointly by the individual authors. 5 6 This library is free software; you can redistribute it and/or modify it 7 under the terms of the GNU Lesser General Public License as published 8 by the Free Software Foundation; either version 3 of the License, or (at 9 your option) any later version. 10 11 This library is distributed in the hope that it will be useful, but WITHOUT 12 ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 License for more details. 15 16 You should have received a copy of the GNU Lesser General Public License 17 along with this library; if not, write to the Free Software Foundation, 18 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 19 20 > http://www.fsf.org/licensing/licenses/lgpl.html 21 > http://www.opensource.org/licenses/lgpl-license.php 22 23 */ 24 package org.dishevelled.collect; 25 26 import java.util.Collections; 27 import java.util.Comparator; 28 import java.util.Map; 29 import java.util.HashMap; 30 import java.util.NavigableMap; 31 import java.util.SortedMap; 32 import java.util.TreeMap; 33 34 import java.util.concurrent.ConcurrentMap; 35 import java.util.concurrent.ConcurrentHashMap; 36 import java.util.concurrent.ConcurrentSkipListMap; 37 38 import org.cliffc.high_scale_lib.NonBlockingHashMap; 39 import org.cliffc.high_scale_lib.NonBlockingHashMapLong; 40 41 import com.google.common.collect.ImmutableMap; 42 import com.google.common.collect.ImmutableSortedMap; 43 44 /** 45 * Static utility methods for Maps. 46 * 47 * @author Michael Heuer 48 * @version $Revision$ $Date$ 49 */ 50 public final class Maps 51 { 52 53 /** 54 * Private no-arg constructor. 55 */ 56 private Maps() 57 { 58 // empty 59 } 60 61 62 /** 63 * Create and return a new empty map. Delegates to <code>Collections.emptyMap()</code>. 64 * 65 * @param <K> key type 66 * @param <V> value type 67 * @return a new empty map 68 */ 69 public static <K, V> Map<K, V> emptyMap() 70 { 71 return Collections.<K, V>emptyMap(); 72 } 73 74 /** 75 * Create and return a new instance of Map. 76 * 77 * @param <K> key type 78 * @param <V> value type 79 * @return a new instance of Map 80 */ 81 public static <K, V> Map<K, V> createMap() 82 { 83 return new HashMap<K, V>(); 84 } 85 86 /** 87 * Create and return a new instance of Map with the specified initial capacity. 88 * 89 * @param <K> key type 90 * @param <V> value type 91 * @param initialCapacity initial capacity 92 * @return a new instance of Map with the specified initial capacity 93 */ 94 public static <K, V> Map<K, V> createMap(final int initialCapacity) 95 { 96 return new HashMap<K, V>(initialCapacity); 97 } 98 99 /** 100 * Create and return a new instance of Map with the specified initial capacity 101 * and load factor. 102 * 103 * @param <K> key type 104 * @param <V> value type 105 * @param initialCapacity initial capacity 106 * @param loadFactor load factor 107 * @return a new instance of Map with the specified initial capacity 108 * and load factor 109 */ 110 public static <K, V> Map<K, V> createMap(final int initialCapacity, final float loadFactor) 111 { 112 return new HashMap<K, V>(initialCapacity, loadFactor); 113 } 114 115 /** 116 * Create and return a new instance of Map with the same mappings as the 117 * specified map. The map is created with default load factor (0.75) and an 118 * initial capacity sufficient to hold the mappings in the specified map. 119 * 120 * @param <K> key type 121 * @param <V> value type 122 * @param map map to copy mappings from 123 * @return a new instance of Map with the same mappings as the 124 * specified map 125 */ 126 public static <K, V> Map<K, V> createMap(final Map<? extends K, ? extends V> map) 127 { 128 return new HashMap<K, V>(map); 129 } 130 131 /** 132 * Create and return a new synchronized (thread-safe) instance of Map. It is 133 * imperative that the user manually synchronize on the returned map when iterating 134 * over any of its collection views: 135 * <pre> 136 * Map m = Maps.newSynchronizedMap(); 137 * ... 138 * Set s = m.keySet(); // Needn't be in synchronized block 139 * ... 140 * synchronized(m) // Synchronizing on m, not s! 141 * { 142 * Iterator i = s.iterator(); // Must be in synchronized block 143 * while (i.hasNext()) 144 * { 145 * foo(i.next()); 146 * } 147 * } 148 * </pre> 149 * Failure to follow this advice may result in non-deterministic behavior. 150 * 151 * @param <K> key type 152 * @param <V> value type 153 * @return a new synchronized (thread-safe) instance of Map 154 */ 155 public static <K, V> Map<K, V> createSynchronizedMap() 156 { 157 return Collections.synchronizedMap(new HashMap<K, V>()); 158 } 159 160 /** 161 * Create and return a new synchronized (thread-safe) instance of Map with 162 * the specified initial capacity. It is imperative that the user manually 163 * synchronize on the returned map when iterating over any of its collection 164 * views: 165 * <pre> 166 * Map m = Maps.newSynchronizedMap(10); 167 * ... 168 * Set s = m.keySet(); // Needn't be in synchronized block 169 * ... 170 * synchronized(m) // Synchronizing on m, not s! 171 * { 172 * Iterator i = s.iterator(); // Must be in synchronized block 173 * while (i.hasNext()) 174 * { 175 * foo(i.next()); 176 * } 177 * } 178 * </pre> 179 * Failure to follow this advice may result in non-deterministic behavior. 180 * 181 * @param <K> key type 182 * @param <V> value type 183 * @param initialCapacity initial capacity 184 * @return a new synchronized (thread-safe) instance of Map with 185 * the specified initial capacity 186 */ 187 public static <K, V> Map<K, V> createSynchronizedMap(final int initialCapacity) 188 { 189 return Collections.synchronizedMap(new HashMap<K, V>(initialCapacity)); 190 } 191 192 /** 193 * Create and return a new synchronized (thread-safe) instance of Map with 194 * the specified initial capacity and load factor. It is imperative that the 195 * user manually synchronize on the returned map when iterating over any of 196 * its collection views: 197 * <pre> 198 * Map m = Maps.newSynchronizedMap(10, 0.80); 199 * ... 200 * Set s = m.keySet(); // Needn't be in synchronized block 201 * ... 202 * synchronized(m) // Synchronizing on m, not s! 203 * { 204 * Iterator i = s.iterator(); // Must be in synchronized block 205 * while (i.hasNext()) 206 * { 207 * foo(i.next()); 208 * } 209 * } 210 * </pre> 211 * Failure to follow this advice may result in non-deterministic behavior. 212 * 213 * @param <K> key type 214 * @param <V> value type 215 * @param initialCapacity initial capacity 216 * @param loadFactor load factor 217 * @return a new synchronized (thread-safe) instance of Map with 218 * the specified intial capacity and load factor 219 */ 220 public static <K, V> Map<K, V> createSynchronizedMap(final int initialCapacity, final float loadFactor) 221 { 222 return Collections.synchronizedMap(new HashMap<K, V>(initialCapacity, loadFactor)); 223 } 224 225 /** 226 * Create and return a new synchronized (thread-safe) instance of Map with 227 * the same mappings as the specified map. The map is created with default load 228 * factor (0.75) and an initial capacity sufficient to hold the mappings in the 229 * specified map. It is imperative that the user manually synchronize on the 230 * returned map when iterating over any of its collection views: 231 * <pre> 232 * Map m = Maps.newSynchronizedMap(map); 233 * ... 234 * Set s = m.keySet(); // Needn't be in synchronized block 235 * ... 236 * synchronized(m) // Synchronizing on m, not s! 237 * { 238 * Iterator i = s.iterator(); // Must be in synchronized block 239 * while (i.hasNext()) 240 * { 241 * foo(i.next()); 242 * } 243 * } 244 * </pre> 245 * Failure to follow this advice may result in non-deterministic behavior. 246 * 247 * @param <K> key type 248 * @param <V> value type 249 * @param map map to copy mappings from 250 * @return a new synchronized (thread-safe) instance of Map with 251 * the same mappings as the specified map 252 */ 253 public static <K, V> Map<K, V> createSynchronizedMap(final Map<? extends K, ? extends V> map) 254 { 255 return Collections.synchronizedMap(new HashMap<K, V>(map)); 256 } 257 258 /** 259 * Create and return a new instance of ConcurrentMap. 260 * 261 * @param <K> key type 262 * @param <V> value type 263 * @return a new instance of ConcurrentMap 264 */ 265 public static <K, V> ConcurrentMap<K, V> createConcurrentMap() 266 { 267 return new ConcurrentHashMap<K, V>(); 268 } 269 270 /** 271 * Create and return a new instance of ConcurrentMap with the specified initial capacity. 272 * 273 * @param <K> key type 274 * @param <V> value type 275 * @param initialCapacity initial capacity 276 * @return a new instance of ConcurrentMap with the specified initial capacity 277 */ 278 public static <K, V> ConcurrentMap<K, V> createConcurrentMap(final int initialCapacity) 279 { 280 return new ConcurrentHashMap<K, V>(initialCapacity); 281 } 282 283 /** 284 * Create and return a new instance of ConcurrentMap with the specified initial capacity 285 * and load factor. 286 * 287 * @param <K> key type 288 * @param <V> value type 289 * @param initialCapacity initial capacity 290 * @param loadFactor load factor 291 * @return a new instance of ConcurrentMap with the specified initial capacity 292 * and load factor 293 */ 294 public static <K, V> ConcurrentMap<K, V> createConcurrentMap(final int initialCapacity, 295 final float loadFactor) 296 { 297 return new ConcurrentHashMap<K, V>(initialCapacity, loadFactor); 298 } 299 300 /** 301 * Create and return a new instance of ConcurrentMap with the specified initial capacity, 302 * load factor, and concurrency level. 303 * 304 * @param <K> key type 305 * @param <V> value type 306 * @param initialCapacity initial capacity 307 * @param loadFactor load factor 308 * @param concurrencyLevel concurrency level 309 * @return a new instance of ConcurrentMap with the specified initial capacity 310 * load factor, and concurrency level 311 */ 312 public static <K, V> ConcurrentMap<K, V> createConcurrentMap(final int initialCapacity, 313 final float loadFactor, 314 final int concurrencyLevel) 315 { 316 return new ConcurrentHashMap<K, V>(initialCapacity, loadFactor, concurrencyLevel); 317 } 318 319 /** 320 * Create and return a new instance of ConcurrentMap with the same mappings as the 321 * specified map. The concurrent map is created with default load factor (0.75) and an 322 * initial capacity sufficient to hold the mappings in the specified map. 323 * 324 * @param <K> key type 325 * @param <V> value type 326 * @param map map to copy mappings from, must not be null 327 * @return a new instance of ConcurrentMap with the same mappings as the 328 * specified map 329 */ 330 public static <K, V> ConcurrentMap<K, V> createConcurrentMap(final Map<? extends K, ? extends V> map) 331 { 332 return new ConcurrentHashMap<K, V>(map); 333 } 334 335 /** 336 * Create and return a new non-blocking implementation of ConcurrentMap. 337 * 338 * @param <K> key type 339 * @param <V> value type 340 * @return a new non-blocking implementation of ConcurrentMap 341 */ 342 public static <K, V> ConcurrentMap<K, V> createNonBlockingMap() 343 { 344 return new NonBlockingHashMap<K, V>(); 345 } 346 347 /** 348 * Create and return a new non-blocking implementation of ConcurrentMap with the 349 * specified initial capacity. 350 * 351 * @param <K> key type 352 * @param <V> value type 353 * @param initialCapacity initial capacity 354 * @return a new non-blocking implementation of ConcurrentMap with the 355 * specified initial capacity 356 */ 357 public static <K, V> ConcurrentMap<K, V> createNonBlockingMap(final int initialCapacity) 358 { 359 return new NonBlockingHashMap<K, V>(initialCapacity); 360 } 361 362 /** 363 * Create and return a new non-blocking implementation of ConcurrentMap with 364 * <code>Long</code>s as keys. 365 * 366 * @param <V> value type 367 * @return a new non-blocking implementation of ConcurrentMap with 368 * <code>Long</code>s as keys 369 */ 370 public static <V> ConcurrentMap<Long, V> createLongNonBlockingMap() 371 { 372 return new NonBlockingHashMapLong<V>(); 373 } 374 375 /** 376 * Create and return a new non-blocking implementation of ConcurrentMap with 377 * <code>Long</code>s as keys. 378 * 379 * @param <V> value type 380 * @param optimizeForSpace true if the implementation should optimize for space 381 * @return a new non-blocking implementation of ConcurrentMap with 382 * <code>Long</code>s as keys 383 */ 384 public static <V> ConcurrentMap<Long, V> createLongNonBlockingMap(final boolean optimizeForSpace) 385 { 386 return new NonBlockingHashMapLong<V>(optimizeForSpace); 387 } 388 389 /** 390 * Create and return a new non-blocking implementation of ConcurrentMap with 391 * the specified initial capacity and <code>Long</code>s as keys. 392 * 393 * @param <V> value type 394 * @param initialCapacity initial capacity 395 * @return a new non-blocking implementation of ConcurrentMap with 396 * the specified initial capacity and <code>Long</code>s as keys 397 */ 398 public static <V> ConcurrentMap<Long, V> createLongNonBlockingMap(final int initialCapacity) 399 { 400 return new NonBlockingHashMapLong<V>(initialCapacity); 401 } 402 403 /** 404 * Create and return a new non-blocking implementation of ConcurrentMap with 405 * the specified initial capacity and <code>Long</code>s as keys. 406 * 407 * @param <V> value type 408 * @param initialCapacity initial capacity 409 * @param optimizeForSpace true if this implementation should optimize for space 410 * @return a new non-blocking implementation of ConcurrentMap with 411 * the specified initial capacity and <code>Long</code>s as keys 412 */ 413 public static <V> ConcurrentMap<Long, V> createLongNonBlockingMap(final int initialCapacity, 414 final boolean optimizeForSpace) 415 { 416 return new NonBlockingHashMapLong<V>(initialCapacity, optimizeForSpace); 417 } 418 419 /** 420 * Create and return a new instance of ConcurrentSkipListMap sorted according 421 * to the natural ordering of its keys. 422 * 423 * @param <K> key type 424 * @param <V> value type 425 * @return a new instance of ConcurrentSkipListMap sorted according 426 * to the natural ordering of its keys 427 */ 428 public static <K, V> ConcurrentSkipListMap<K, V> createConcurrentSkipListMap() 429 { 430 return new ConcurrentSkipListMap<K, V>(); 431 } 432 433 /** 434 * Create and return a new instance of ConcurrentSkipListMap sorted according 435 * to the specified comparator. 436 * 437 * @param <K> key type 438 * @param <V> value type 439 * @param comparator comparator that will be used to order this map, or 440 * <code>null</code> to use the natural ordering of its keys 441 * @return a new instance of ConcurrentSkipListMap sorted according 442 * to the specified comparator 443 */ 444 public static <K, V> ConcurrentSkipListMap<K, V> createConcurrentSkipListMap(final Comparator<? super K> comparator) 445 { 446 return new ConcurrentSkipListMap<K, V>(comparator); 447 } 448 449 /** 450 * Create and return a new instance of ConcurrentSkipListMap containing the 451 * same mappings as the specified map and sorted according to the natural ordering of 452 * its keys. 453 * 454 * @param <K> key type 455 * @param <V> value type 456 * @param map map to copy mappings from, must not be null 457 * @return a new instance of ConcurrentSkipListMap containing the 458 * same mappings as the specified map and sorted according to the natural ordering of 459 * its keys 460 */ 461 public static <K, V> ConcurrentSkipListMap<K, V> createConcurrentSkipListMap(final Map<? extends K, ? extends V> map) 462 { 463 return new ConcurrentSkipListMap<K, V>(map); 464 } 465 466 /** 467 * Create and return a new instance of ConcurrentSkipListMap containing the 468 * same mappings and using the same ordering as the specified sorted map. 469 * 470 * @param <K> key type 471 * @param <V> value type 472 * @param sortedMap sorted map to copy mappings and ordering from, must not be null 473 * @return a new instance of ConcurrentSkipListMap containing the 474 * same mappings and using the same ordering as the specified sorted map 475 */ 476 public static <K, V> ConcurrentSkipListMap<K, V> createConcurrentSkipListMap(final SortedMap<K, ? extends V> sortedMap) 477 { 478 return new ConcurrentSkipListMap<K, V>(sortedMap); 479 } 480 481 /** 482 * Create and return a new instance of SortedMap using the natural ordering of its keys. 483 * 484 * @param <K> key type 485 * @param <V> value type 486 * @return a new instance of SortedMap using the natural ordering of its keys 487 */ 488 public static <K, V> SortedMap<K, V> createSortedMap() 489 { 490 return new TreeMap<K, V>(); 491 } 492 493 /** 494 * Create and return a new instance of SortedMap ordered according to the specified comparator. 495 * 496 * @param <K> key type 497 * @param <V> value type 498 * @param comparator comparator used to order this map, or <code>null</code> to use the 499 * natural ordering of its keys 500 * @return a new instance of SortedMap ordered according to the specified comparator 501 */ 502 public static <K, V> SortedMap<K, V> createSortedMap(final Comparator<? super K> comparator) 503 { 504 return new TreeMap<K, V>(comparator); 505 } 506 507 /** 508 * Create and return a new instance of SortedMap containing the same mappings as the specified 509 * map ordered according to the natural ordering of its keys. 510 * 511 * @param <K> key type 512 * @param <V> value type 513 * @param map map to copy mappings from, must not be null 514 * @return a new instance of SortedMap containing the same mappings as the specified 515 * map ordered according to the natural ordering of its keys 516 */ 517 public static <K, V> SortedMap<K, V> createSortedMap(final Map<? extends K, ? extends V> map) 518 { 519 return new TreeMap<K, V>(map); 520 } 521 522 /** 523 * Create and return a new instance of SortedMap containing the same mappings and the same 524 * ordering as the specified sorted map. 525 * 526 * @param <K> key type 527 * @param <V> value type 528 * @param sortedMap sorted map to copy mappings and comparator from, must not be null 529 * @return a new instance of SortedMap containing the same mappings and the same 530 * ordering as the specified sorted map 531 */ 532 public static <K, V> SortedMap<K, V> createSortedMap(final SortedMap<K, ? extends V> sortedMap) 533 { 534 return new TreeMap<K, V>(sortedMap); 535 } 536 537 /** 538 * Create and return a new instance of NavigableMap using the natural ordering of its keys. 539 * 540 * @param <K> key type 541 * @param <V> value type 542 * @return a new instance of NavigableMap using the natural ordering of its keys 543 */ 544 public static <K, V> NavigableMap<K, V> createNavigableMap() 545 { 546 return new TreeMap<K, V>(); 547 } 548 549 /** 550 * Create and return a new instance of NavigableMap ordered according to the specified comparator. 551 * 552 * @param <K> key type 553 * @param <V> value type 554 * @param comparator comparator used to order this map, or <code>null</code> to use the 555 * natural ordering of its keys 556 * @return a new instance of NavigableMap ordered according to the specified comparator 557 */ 558 public static <K, V> NavigableMap<K, V> createNavigableMap(final Comparator<? super K> comparator) 559 { 560 return new TreeMap<K, V>(comparator); 561 } 562 563 /** 564 * Create and return a new instance of NavigableMap containing the same mappings as the specified 565 * map ordered according to the natural ordering of its keys. 566 * 567 * @param <K> key type 568 * @param <V> value type 569 * @param map map to copy mappings from, must not be null 570 * @return a new instance of NavigableMap containing the same mappings as the specified 571 * map ordered according to the natural ordering of its keys 572 */ 573 public static <K, V> NavigableMap<K, V> createNavigableMap(final Map<? extends K, ? extends V> map) 574 { 575 return new TreeMap<K, V>(map); 576 } 577 578 /** 579 * Create and return a new instance of NavigableMap containing the same mappings and the same 580 * ordering as the specified navigable map. 581 * 582 * @param <K> key type 583 * @param <V> value type 584 * @param navigableMap navigable map to copy mappings and comparator from, must not be null 585 * @return a new instance of NavigableMap containing the same mappings and the same 586 * ordering as the specified navigable map 587 */ 588 public static <K, V> NavigableMap<K, V> createNavigableMap(final NavigableMap<K, ? extends V> navigableMap) 589 { 590 return new TreeMap<K, V>(navigableMap); 591 } 592 593 /** 594 * Create and return a new unmodifiable view of the specified map. Query operations on 595 * the returned map "read through" to the specified map. Attempts to modify the returned map, 596 * whether direct or via its collection views, result in an <code>UnsupportedOperationException</code>. 597 * 598 * @param <K> key type 599 * @param <V> value type 600 * @param map map to view, must not be null 601 * @return a new unmodifiable view of the specified map 602 */ 603 public static <K, V> Map<K, V> unmodifiableMap(final Map<? extends K, ? extends V> map) 604 { 605 return Collections.unmodifiableMap(map); 606 } 607 608 /** 609 * Create and return a new unmodifiable view of the specified sorted map. Query operations on 610 * the returned sorted map "read through" to the specified sorted map. Attempts to modify the 611 * returned sorted map, whether direct, via its collection views, or via its <code>subMap</code>, 612 * <code>headMap</code>, or <code>tailMap</code> views, result in an 613 * <code>UnsupportedOperationException</code>. 614 * 615 * @param <K> key type 616 * @param <V> value type 617 * @param sortedMap sorted map to view, must not be null 618 * @return a new unmodifiable view of the specified sorted map 619 */ 620 public static <K, V> SortedMap<K, V> unmodifiableSortedMap(final SortedMap<K, ? extends V> sortedMap) 621 { 622 return Collections.unmodifiableSortedMap(sortedMap); 623 } 624 625 /** 626 * Create and return an immutable map containing the same mappings as the specified map. 627 * 628 * @param <K> key type 629 * @param <V> value type 630 * @param map map to copy, must not be null 631 * @return an immutable map containing the same mappings as the specified map 632 */ 633 public static <K, V> Map<K, V> immutableMap(final Map<? extends K, ? extends V> map) 634 { 635 return ImmutableMap.copyOf(map); 636 } 637 638 /** 639 * Create and return an immutable sorted map containing the same mappings and the same 640 * ordering as the specified sorted map. 641 * 642 * @param <K> key type 643 * @param <V> value type 644 * @param sortedMap sorted map to copy, must not be null 645 * @return an immutable sorted map containing the same mappings and the same 646 * ordering as the specified sorted map 647 */ 648 public static <K, V> SortedMap<K, V> immutableSortedMap(final SortedMap<K, ? extends V> sortedMap) 649 { 650 return ImmutableSortedMap.copyOfSorted(sortedMap); 651 } 652 }