1 /*
2
3 dsh-collect Collection and map utility classes.
4 Copyright (c) 2008-2012 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 }