001/* 002 * Copyright (C) 2009 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.google.common.collect; 018 019import static com.google.common.base.Preconditions.checkArgument; 020import static com.google.common.base.Preconditions.checkNotNull; 021import static com.google.common.collect.CollectPreconditions.checkEntryNotNull; 022import static com.google.common.collect.Maps.keyOrNull; 023import static java.util.Objects.requireNonNull; 024 025import com.google.common.annotations.Beta; 026import com.google.common.annotations.GwtCompatible; 027import com.google.errorprone.annotations.CanIgnoreReturnValue; 028import com.google.errorprone.annotations.DoNotCall; 029import java.util.AbstractMap; 030import java.util.Arrays; 031import java.util.Comparator; 032import java.util.Map; 033import java.util.NavigableMap; 034import java.util.SortedMap; 035import java.util.Spliterator; 036import java.util.TreeMap; 037import java.util.function.BiConsumer; 038import java.util.function.BinaryOperator; 039import java.util.function.Consumer; 040import java.util.function.Function; 041import java.util.stream.Collector; 042import java.util.stream.Collectors; 043import javax.annotation.CheckForNull; 044import org.checkerframework.checker.nullness.qual.Nullable; 045 046/** 047 * A {@link NavigableMap} whose contents will never change, with many other important properties 048 * detailed at {@link ImmutableCollection}. 049 * 050 * <p><b>Warning:</b> as with any sorted collection, you are strongly advised not to use a {@link 051 * Comparator} or {@link Comparable} type whose comparison behavior is <i>inconsistent with 052 * equals</i>. That is, {@code a.compareTo(b)} or {@code comparator.compare(a, b)} should equal zero 053 * <i>if and only if</i> {@code a.equals(b)}. If this advice is not followed, the resulting map will 054 * not correctly obey its specification. 055 * 056 * <p>See the Guava User Guide article on <a href= 057 * "https://github.com/google/guava/wiki/ImmutableCollectionsExplained"> immutable collections</a>. 058 * 059 * @author Jared Levy 060 * @author Louis Wasserman 061 * @since 2.0 (implements {@code NavigableMap} since 12.0) 062 */ 063@GwtCompatible(serializable = true, emulated = true) 064@ElementTypesAreNonnullByDefault 065public final class ImmutableSortedMap<K, V> extends ImmutableSortedMapFauxverideShim<K, V> 066 implements NavigableMap<K, V> { 067 /** 068 * Returns a {@link Collector} that accumulates elements into an {@code ImmutableSortedMap} whose 069 * keys and values are the result of applying the provided mapping functions to the input 070 * elements. The generated map is sorted by the specified comparator. 071 * 072 * <p>If the mapped keys contain duplicates (according to the specified comparator), an {@code 073 * IllegalArgumentException} is thrown when the collection operation is performed. (This differs 074 * from the {@code Collector} returned by {@link Collectors#toMap(Function, Function)}, which 075 * throws an {@code IllegalStateException}.) 076 * 077 * @since 21.0 078 */ 079 public static <T extends @Nullable Object, K, V> 080 Collector<T, ?, ImmutableSortedMap<K, V>> toImmutableSortedMap( 081 Comparator<? super K> comparator, 082 Function<? super T, ? extends K> keyFunction, 083 Function<? super T, ? extends V> valueFunction) { 084 return CollectCollectors.toImmutableSortedMap(comparator, keyFunction, valueFunction); 085 } 086 087 /** 088 * Returns a {@link Collector} that accumulates elements into an {@code ImmutableSortedMap} whose 089 * keys and values are the result of applying the provided mapping functions to the input 090 * elements. 091 * 092 * <p>If the mapped keys contain duplicates (according to the comparator), the the values are 093 * merged using the specified merging function. Entries will appear in the encounter order of the 094 * first occurrence of the key. 095 * 096 * @since 21.0 097 */ 098 public static <T extends @Nullable Object, K, V> 099 Collector<T, ?, ImmutableSortedMap<K, V>> toImmutableSortedMap( 100 Comparator<? super K> comparator, 101 Function<? super T, ? extends K> keyFunction, 102 Function<? super T, ? extends V> valueFunction, 103 BinaryOperator<V> mergeFunction) { 104 return CollectCollectors.toImmutableSortedMap( 105 comparator, keyFunction, valueFunction, mergeFunction); 106 } 107 108 /* 109 * TODO(kevinb): Confirm that ImmutableSortedMap is faster to construct and 110 * uses less memory than TreeMap; then say so in the class Javadoc. 111 */ 112 private static final Comparator<Comparable> NATURAL_ORDER = Ordering.natural(); 113 114 private static final ImmutableSortedMap<Comparable, Object> NATURAL_EMPTY_MAP = 115 new ImmutableSortedMap<>( 116 ImmutableSortedSet.emptySet(Ordering.natural()), ImmutableList.<Object>of()); 117 118 static <K, V> ImmutableSortedMap<K, V> emptyMap(Comparator<? super K> comparator) { 119 if (Ordering.natural().equals(comparator)) { 120 return of(); 121 } else { 122 return new ImmutableSortedMap<>( 123 ImmutableSortedSet.emptySet(comparator), ImmutableList.<V>of()); 124 } 125 } 126 127 /** 128 * Returns the empty sorted map. 129 * 130 * <p><b>Performance note:</b> the instance returned is a singleton. 131 */ 132 @SuppressWarnings("unchecked") 133 // unsafe, comparator() returns a comparator on the specified type 134 // TODO(kevinb): evaluate whether or not of().comparator() should return null 135 public static <K, V> ImmutableSortedMap<K, V> of() { 136 return (ImmutableSortedMap<K, V>) NATURAL_EMPTY_MAP; 137 } 138 139 /** Returns an immutable map containing a single entry. */ 140 public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> of(K k1, V v1) { 141 return of(Ordering.natural(), k1, v1); 142 } 143 144 /** Returns an immutable map containing a single entry. */ 145 private static <K, V> ImmutableSortedMap<K, V> of(Comparator<? super K> comparator, K k1, V v1) { 146 return new ImmutableSortedMap<>( 147 new RegularImmutableSortedSet<K>(ImmutableList.of(k1), checkNotNull(comparator)), 148 ImmutableList.of(v1)); 149 } 150 151 /** 152 * Returns an immutable sorted map containing the given entries, sorted by the natural ordering of 153 * their keys. 154 * 155 * @throws IllegalArgumentException if the two keys are equal according to their natural ordering 156 */ 157 @SuppressWarnings("unchecked") 158 public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> of( 159 K k1, V v1, K k2, V v2) { 160 return fromEntries(entryOf(k1, v1), entryOf(k2, v2)); 161 } 162 163 /** 164 * Returns an immutable sorted map containing the given entries, sorted by the natural ordering of 165 * their keys. 166 * 167 * @throws IllegalArgumentException if any two keys are equal according to their natural ordering 168 */ 169 @SuppressWarnings("unchecked") 170 public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> of( 171 K k1, V v1, K k2, V v2, K k3, V v3) { 172 return fromEntries(entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3)); 173 } 174 175 /** 176 * Returns an immutable sorted map containing the given entries, sorted by the natural ordering of 177 * their keys. 178 * 179 * @throws IllegalArgumentException if any two keys are equal according to their natural ordering 180 */ 181 @SuppressWarnings("unchecked") 182 public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> of( 183 K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { 184 return fromEntries(entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4)); 185 } 186 187 /** 188 * Returns an immutable sorted map containing the given entries, sorted by the natural ordering of 189 * their keys. 190 * 191 * @throws IllegalArgumentException if any two keys are equal according to their natural ordering 192 */ 193 @SuppressWarnings("unchecked") 194 public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> of( 195 K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { 196 return fromEntries( 197 entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4), entryOf(k5, v5)); 198 } 199 200 /** 201 * Returns an immutable sorted map containing the given entries, sorted by the natural ordering of 202 * their keys. 203 * 204 * @throws IllegalArgumentException if any two keys are equal according to their natural ordering 205 * @since 31.0 206 */ 207 @SuppressWarnings("unchecked") 208 public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> of( 209 K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6) { 210 return fromEntries( 211 entryOf(k1, v1), 212 entryOf(k2, v2), 213 entryOf(k3, v3), 214 entryOf(k4, v4), 215 entryOf(k5, v5), 216 entryOf(k6, v6)); 217 } 218 219 /** 220 * Returns an immutable sorted map containing the given entries, sorted by the natural ordering of 221 * their keys. 222 * 223 * @throws IllegalArgumentException if any two keys are equal according to their natural ordering 224 * @since 31.0 225 */ 226 @SuppressWarnings("unchecked") 227 public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> of( 228 K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7) { 229 return fromEntries( 230 entryOf(k1, v1), 231 entryOf(k2, v2), 232 entryOf(k3, v3), 233 entryOf(k4, v4), 234 entryOf(k5, v5), 235 entryOf(k6, v6), 236 entryOf(k7, v7)); 237 } 238 239 /** 240 * Returns an immutable sorted map containing the given entries, sorted by the natural ordering of 241 * their keys. 242 * 243 * @throws IllegalArgumentException if any two keys are equal according to their natural ordering 244 * @since 31.0 245 */ 246 @SuppressWarnings("unchecked") 247 public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> of( 248 K k1, 249 V v1, 250 K k2, 251 V v2, 252 K k3, 253 V v3, 254 K k4, 255 V v4, 256 K k5, 257 V v5, 258 K k6, 259 V v6, 260 K k7, 261 V v7, 262 K k8, 263 V v8) { 264 return fromEntries( 265 entryOf(k1, v1), 266 entryOf(k2, v2), 267 entryOf(k3, v3), 268 entryOf(k4, v4), 269 entryOf(k5, v5), 270 entryOf(k6, v6), 271 entryOf(k7, v7), 272 entryOf(k8, v8)); 273 } 274 275 /** 276 * Returns an immutable sorted map containing the given entries, sorted by the natural ordering of 277 * their keys. 278 * 279 * @throws IllegalArgumentException if any two keys are equal according to their natural ordering 280 * @since 31.0 281 */ 282 @SuppressWarnings("unchecked") 283 public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> of( 284 K k1, 285 V v1, 286 K k2, 287 V v2, 288 K k3, 289 V v3, 290 K k4, 291 V v4, 292 K k5, 293 V v5, 294 K k6, 295 V v6, 296 K k7, 297 V v7, 298 K k8, 299 V v8, 300 K k9, 301 V v9) { 302 return fromEntries( 303 entryOf(k1, v1), 304 entryOf(k2, v2), 305 entryOf(k3, v3), 306 entryOf(k4, v4), 307 entryOf(k5, v5), 308 entryOf(k6, v6), 309 entryOf(k7, v7), 310 entryOf(k8, v8), 311 entryOf(k9, v9)); 312 } 313 314 /** 315 * Returns an immutable sorted map containing the given entries, sorted by the natural ordering of 316 * their keys. 317 * 318 * @throws IllegalArgumentException if any two keys are equal according to their natural ordering 319 * @since 31.0 320 */ 321 @SuppressWarnings("unchecked") 322 public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> of( 323 K k1, 324 V v1, 325 K k2, 326 V v2, 327 K k3, 328 V v3, 329 K k4, 330 V v4, 331 K k5, 332 V v5, 333 K k6, 334 V v6, 335 K k7, 336 V v7, 337 K k8, 338 V v8, 339 K k9, 340 V v9, 341 K k10, 342 V v10) { 343 return fromEntries( 344 entryOf(k1, v1), 345 entryOf(k2, v2), 346 entryOf(k3, v3), 347 entryOf(k4, v4), 348 entryOf(k5, v5), 349 entryOf(k6, v6), 350 entryOf(k7, v7), 351 entryOf(k8, v8), 352 entryOf(k9, v9), 353 entryOf(k10, v10)); 354 } 355 356 /** 357 * Returns an immutable map containing the same entries as {@code map}, sorted by the natural 358 * ordering of the keys. 359 * 360 * <p>Despite the method name, this method attempts to avoid actually copying the data when it is 361 * safe to do so. The exact circumstances under which a copy will or will not be performed are 362 * undocumented and subject to change. 363 * 364 * <p>This method is not type-safe, as it may be called on a map with keys that are not mutually 365 * comparable. 366 * 367 * @throws ClassCastException if the keys in {@code map} are not mutually comparable 368 * @throws NullPointerException if any key or value in {@code map} is null 369 * @throws IllegalArgumentException if any two keys are equal according to their natural ordering 370 */ 371 public static <K, V> ImmutableSortedMap<K, V> copyOf(Map<? extends K, ? extends V> map) { 372 // Hack around K not being a subtype of Comparable. 373 // Unsafe, see ImmutableSortedSetFauxverideShim. 374 @SuppressWarnings("unchecked") 375 Ordering<K> naturalOrder = (Ordering<K>) NATURAL_ORDER; 376 return copyOfInternal(map, naturalOrder); 377 } 378 379 /** 380 * Returns an immutable map containing the same entries as {@code map}, with keys sorted by the 381 * provided comparator. 382 * 383 * <p>Despite the method name, this method attempts to avoid actually copying the data when it is 384 * safe to do so. The exact circumstances under which a copy will or will not be performed are 385 * undocumented and subject to change. 386 * 387 * @throws NullPointerException if any key or value in {@code map} is null 388 * @throws IllegalArgumentException if any two keys are equal according to the comparator 389 */ 390 public static <K, V> ImmutableSortedMap<K, V> copyOf( 391 Map<? extends K, ? extends V> map, Comparator<? super K> comparator) { 392 return copyOfInternal(map, checkNotNull(comparator)); 393 } 394 395 /** 396 * Returns an immutable map containing the given entries, with keys sorted by their natural 397 * ordering. 398 * 399 * <p>This method is not type-safe, as it may be called on a map with keys that are not mutually 400 * comparable. 401 * 402 * @throws NullPointerException if any key or value in {@code map} is null 403 * @throws IllegalArgumentException if any two keys are equal according to the comparator 404 * @since 19.0 405 */ 406 @Beta 407 public static <K, V> ImmutableSortedMap<K, V> copyOf( 408 Iterable<? extends Entry<? extends K, ? extends V>> entries) { 409 // Hack around K not being a subtype of Comparable. 410 // Unsafe, see ImmutableSortedSetFauxverideShim. 411 @SuppressWarnings("unchecked") 412 Ordering<K> naturalOrder = (Ordering<K>) NATURAL_ORDER; 413 return copyOf(entries, naturalOrder); 414 } 415 416 /** 417 * Returns an immutable map containing the given entries, with keys sorted by the provided 418 * comparator. 419 * 420 * @throws NullPointerException if any key or value in {@code map} is null 421 * @throws IllegalArgumentException if any two keys are equal according to the comparator 422 * @since 19.0 423 */ 424 @Beta 425 public static <K, V> ImmutableSortedMap<K, V> copyOf( 426 Iterable<? extends Entry<? extends K, ? extends V>> entries, 427 Comparator<? super K> comparator) { 428 return fromEntries(checkNotNull(comparator), false, entries); 429 } 430 431 /** 432 * Returns an immutable map containing the same entries as the provided sorted map, with the same 433 * ordering. 434 * 435 * <p>Despite the method name, this method attempts to avoid actually copying the data when it is 436 * safe to do so. The exact circumstances under which a copy will or will not be performed are 437 * undocumented and subject to change. 438 * 439 * @throws NullPointerException if any key or value in {@code map} is null 440 */ 441 @SuppressWarnings("unchecked") 442 public static <K, V> ImmutableSortedMap<K, V> copyOfSorted(SortedMap<K, ? extends V> map) { 443 Comparator<? super K> comparator = map.comparator(); 444 if (comparator == null) { 445 // If map has a null comparator, the keys should have a natural ordering, 446 // even though K doesn't explicitly implement Comparable. 447 comparator = (Comparator<? super K>) NATURAL_ORDER; 448 } 449 if (map instanceof ImmutableSortedMap) { 450 // TODO(kevinb): Prove that this cast is safe, even though 451 // Collections.unmodifiableSortedMap requires the same key type. 452 @SuppressWarnings("unchecked") 453 ImmutableSortedMap<K, V> kvMap = (ImmutableSortedMap<K, V>) map; 454 if (!kvMap.isPartialView()) { 455 return kvMap; 456 } 457 } 458 return fromEntries(comparator, true, map.entrySet()); 459 } 460 461 private static <K, V> ImmutableSortedMap<K, V> copyOfInternal( 462 Map<? extends K, ? extends V> map, Comparator<? super K> comparator) { 463 boolean sameComparator = false; 464 if (map instanceof SortedMap) { 465 SortedMap<?, ?> sortedMap = (SortedMap<?, ?>) map; 466 Comparator<?> comparator2 = sortedMap.comparator(); 467 sameComparator = 468 (comparator2 == null) ? comparator == NATURAL_ORDER : comparator.equals(comparator2); 469 } 470 471 if (sameComparator && (map instanceof ImmutableSortedMap)) { 472 // TODO(kevinb): Prove that this cast is safe, even though 473 // Collections.unmodifiableSortedMap requires the same key type. 474 @SuppressWarnings("unchecked") 475 ImmutableSortedMap<K, V> kvMap = (ImmutableSortedMap<K, V>) map; 476 if (!kvMap.isPartialView()) { 477 return kvMap; 478 } 479 } 480 return fromEntries(comparator, sameComparator, map.entrySet()); 481 } 482 483 private static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> fromEntries( 484 Entry<K, V>... entries) { 485 return fromEntries(Ordering.natural(), false, entries, entries.length); 486 } 487 488 /** 489 * Accepts a collection of possibly-null entries. If {@code sameComparator}, then it is assumed 490 * that they do not need to be sorted or checked for dupes. 491 */ 492 private static <K, V> ImmutableSortedMap<K, V> fromEntries( 493 Comparator<? super K> comparator, 494 boolean sameComparator, 495 Iterable<? extends Entry<? extends K, ? extends V>> entries) { 496 // "adding" type params to an array of a raw type should be safe as 497 // long as no one can ever cast that same array instance back to a 498 // raw type. 499 @SuppressWarnings("unchecked") 500 Entry<K, V>[] entryArray = (Entry[]) Iterables.toArray(entries, EMPTY_ENTRY_ARRAY); 501 return fromEntries(comparator, sameComparator, entryArray, entryArray.length); 502 } 503 504 private static <K, V> ImmutableSortedMap<K, V> fromEntries( 505 final Comparator<? super K> comparator, 506 boolean sameComparator, 507 @Nullable Entry<K, V>[] entryArray, 508 int size) { 509 switch (size) { 510 case 0: 511 return emptyMap(comparator); 512 case 1: 513 // requireNonNull is safe because the first `size` elements have been filled in. 514 Entry<K, V> onlyEntry = requireNonNull(entryArray[0]); 515 return of(comparator, onlyEntry.getKey(), onlyEntry.getValue()); 516 default: 517 Object[] keys = new Object[size]; 518 Object[] values = new Object[size]; 519 if (sameComparator) { 520 // Need to check for nulls, but don't need to sort or validate. 521 for (int i = 0; i < size; i++) { 522 // requireNonNull is safe because the first `size` elements have been filled in. 523 Entry<K, V> entry = requireNonNull(entryArray[i]); 524 Object key = entry.getKey(); 525 Object value = entry.getValue(); 526 checkEntryNotNull(key, value); 527 keys[i] = key; 528 values[i] = value; 529 } 530 } else { 531 // Need to sort and check for nulls and dupes. 532 // Inline the Comparator implementation rather than transforming with a Function 533 // to save code size. 534 Arrays.sort( 535 entryArray, 536 0, 537 size, 538 new Comparator<@Nullable Entry<K, V>>() { 539 @Override 540 public int compare(@CheckForNull Entry<K, V> e1, @CheckForNull Entry<K, V> e2) { 541 // requireNonNull is safe because the first `size` elements have been filled in. 542 requireNonNull(e1); 543 requireNonNull(e2); 544 return comparator.compare(e1.getKey(), e2.getKey()); 545 } 546 }); 547 // requireNonNull is safe because the first `size` elements have been filled in. 548 Entry<K, V> firstEntry = requireNonNull(entryArray[0]); 549 K prevKey = firstEntry.getKey(); 550 keys[0] = prevKey; 551 values[0] = firstEntry.getValue(); 552 checkEntryNotNull(keys[0], values[0]); 553 for (int i = 1; i < size; i++) { 554 // requireNonNull is safe because the first `size` elements have been filled in. 555 Entry<K, V> prevEntry = requireNonNull(entryArray[i - 1]); 556 Entry<K, V> entry = requireNonNull(entryArray[i]); 557 K key = entry.getKey(); 558 V value = entry.getValue(); 559 checkEntryNotNull(key, value); 560 keys[i] = key; 561 values[i] = value; 562 checkNoConflict(comparator.compare(prevKey, key) != 0, "key", prevEntry, entry); 563 prevKey = key; 564 } 565 } 566 return new ImmutableSortedMap<>( 567 new RegularImmutableSortedSet<K>(new RegularImmutableList<K>(keys), comparator), 568 new RegularImmutableList<V>(values)); 569 } 570 } 571 572 /** 573 * Returns a builder that creates immutable sorted maps whose keys are ordered by their natural 574 * ordering. The sorted maps use {@link Ordering#natural()} as the comparator. 575 */ 576 public static <K extends Comparable<?>, V> Builder<K, V> naturalOrder() { 577 return new Builder<>(Ordering.natural()); 578 } 579 580 /** 581 * Returns a builder that creates immutable sorted maps with an explicit comparator. If the 582 * comparator has a more general type than the map's keys, such as creating a {@code 583 * SortedMap<Integer, String>} with a {@code Comparator<Number>}, use the {@link Builder} 584 * constructor instead. 585 * 586 * @throws NullPointerException if {@code comparator} is null 587 */ 588 public static <K, V> Builder<K, V> orderedBy(Comparator<K> comparator) { 589 return new Builder<>(comparator); 590 } 591 592 /** 593 * Returns a builder that creates immutable sorted maps whose keys are ordered by the reverse of 594 * their natural ordering. 595 */ 596 public static <K extends Comparable<?>, V> Builder<K, V> reverseOrder() { 597 return new Builder<>(Ordering.natural().reverse()); 598 } 599 600 /** 601 * A builder for creating immutable sorted map instances, especially {@code public static final} 602 * maps ("constant maps"). Example: 603 * 604 * <pre>{@code 605 * static final ImmutableSortedMap<Integer, String> INT_TO_WORD = 606 * new ImmutableSortedMap.Builder<Integer, String>(Ordering.natural()) 607 * .put(1, "one") 608 * .put(2, "two") 609 * .put(3, "three") 610 * .buildOrThrow(); 611 * }</pre> 612 * 613 * <p>For <i>small</i> immutable sorted maps, the {@code ImmutableSortedMap.of()} methods are even 614 * more convenient. 615 * 616 * <p>Builder instances can be reused - it is safe to call {@link #buildOrThrow} multiple times to 617 * build multiple maps in series. Each map is a superset of the maps created before it. 618 * 619 * @since 2.0 620 */ 621 public static class Builder<K, V> extends ImmutableMap.Builder<K, V> { 622 private final Comparator<? super K> comparator; 623 624 /** 625 * Creates a new builder. The returned builder is equivalent to the builder generated by {@link 626 * ImmutableSortedMap#orderedBy}. 627 */ 628 @SuppressWarnings("unchecked") 629 public Builder(Comparator<? super K> comparator) { 630 this.comparator = checkNotNull(comparator); 631 } 632 633 /** 634 * Associates {@code key} with {@code value} in the built map. Duplicate keys, according to the 635 * comparator (which might be the keys' natural order), are not allowed, and will cause {@link 636 * #build} to fail. 637 */ 638 @CanIgnoreReturnValue 639 @Override 640 public Builder<K, V> put(K key, V value) { 641 super.put(key, value); 642 return this; 643 } 644 645 /** 646 * Adds the given {@code entry} to the map, making it immutable if necessary. Duplicate keys, 647 * according to the comparator (which might be the keys' natural order), are not allowed, and 648 * will cause {@link #build} to fail. 649 * 650 * @since 11.0 651 */ 652 @CanIgnoreReturnValue 653 @Override 654 public Builder<K, V> put(Entry<? extends K, ? extends V> entry) { 655 super.put(entry); 656 return this; 657 } 658 659 /** 660 * Associates all of the given map's keys and values in the built map. Duplicate keys, according 661 * to the comparator (which might be the keys' natural order), are not allowed, and will cause 662 * {@link #build} to fail. 663 * 664 * @throws NullPointerException if any key or value in {@code map} is null 665 */ 666 @CanIgnoreReturnValue 667 @Override 668 public Builder<K, V> putAll(Map<? extends K, ? extends V> map) { 669 super.putAll(map); 670 return this; 671 } 672 673 /** 674 * Adds all the given entries to the built map. Duplicate keys, according to the comparator 675 * (which might be the keys' natural order), are not allowed, and will cause {@link #build} to 676 * fail. 677 * 678 * @throws NullPointerException if any key, value, or entry is null 679 * @since 19.0 680 */ 681 @CanIgnoreReturnValue 682 @Beta 683 @Override 684 public Builder<K, V> putAll(Iterable<? extends Entry<? extends K, ? extends V>> entries) { 685 super.putAll(entries); 686 return this; 687 } 688 689 /** 690 * Throws an {@code UnsupportedOperationException}. 691 * 692 * @since 19.0 693 * @deprecated Unsupported by ImmutableSortedMap.Builder. 694 */ 695 @CanIgnoreReturnValue 696 @Beta 697 @Override 698 @Deprecated 699 @DoNotCall("Always throws UnsupportedOperationException") 700 public final Builder<K, V> orderEntriesByValue(Comparator<? super V> valueComparator) { 701 throw new UnsupportedOperationException("Not available on ImmutableSortedMap.Builder"); 702 } 703 704 @Override 705 Builder<K, V> combine(ImmutableMap.Builder<K, V> other) { 706 super.combine(other); 707 return this; 708 } 709 710 /** 711 * Returns a newly-created immutable sorted map. 712 * 713 * <p>Prefer the equivalent method {@link #buildOrThrow()} to make it explicit that the method 714 * will throw an exception if there are duplicate keys. The {@code build()} method will soon be 715 * deprecated. 716 * 717 * @throws IllegalArgumentException if any two keys are equal according to the comparator (which 718 * might be the keys' natural order) 719 */ 720 @Override 721 public ImmutableSortedMap<K, V> build() { 722 return buildOrThrow(); 723 } 724 725 /** 726 * Returns a newly-created immutable sorted map, or throws an exception if any two keys are 727 * equal. 728 * 729 * @throws IllegalArgumentException if any two keys are equal according to the comparator (which 730 * might be the keys' natural order) 731 * @since 31.0 732 */ 733 @Override 734 public ImmutableSortedMap<K, V> buildOrThrow() { 735 switch (size) { 736 case 0: 737 return emptyMap(comparator); 738 case 1: 739 // requireNonNull is safe because the first `size` elements have been filled in. 740 Entry<K, V> onlyEntry = requireNonNull(entries[0]); 741 return of(comparator, onlyEntry.getKey(), onlyEntry.getValue()); 742 default: 743 return fromEntries(comparator, false, entries, size); 744 } 745 } 746 } 747 748 private final transient RegularImmutableSortedSet<K> keySet; 749 private final transient ImmutableList<V> valueList; 750 @CheckForNull private transient ImmutableSortedMap<K, V> descendingMap; 751 752 ImmutableSortedMap(RegularImmutableSortedSet<K> keySet, ImmutableList<V> valueList) { 753 this(keySet, valueList, null); 754 } 755 756 ImmutableSortedMap( 757 RegularImmutableSortedSet<K> keySet, 758 ImmutableList<V> valueList, 759 @CheckForNull ImmutableSortedMap<K, V> descendingMap) { 760 this.keySet = keySet; 761 this.valueList = valueList; 762 this.descendingMap = descendingMap; 763 } 764 765 @Override 766 public int size() { 767 return valueList.size(); 768 } 769 770 @Override 771 public void forEach(BiConsumer<? super K, ? super V> action) { 772 checkNotNull(action); 773 ImmutableList<K> keyList = keySet.asList(); 774 for (int i = 0; i < size(); i++) { 775 action.accept(keyList.get(i), valueList.get(i)); 776 } 777 } 778 779 @Override 780 @CheckForNull 781 public V get(@CheckForNull Object key) { 782 int index = keySet.indexOf(key); 783 return (index == -1) ? null : valueList.get(index); 784 } 785 786 @Override 787 boolean isPartialView() { 788 return keySet.isPartialView() || valueList.isPartialView(); 789 } 790 791 /** Returns an immutable set of the mappings in this map, sorted by the key ordering. */ 792 @Override 793 public ImmutableSet<Entry<K, V>> entrySet() { 794 return super.entrySet(); 795 } 796 797 @Override 798 ImmutableSet<Entry<K, V>> createEntrySet() { 799 class EntrySet extends ImmutableMapEntrySet<K, V> { 800 @Override 801 public UnmodifiableIterator<Entry<K, V>> iterator() { 802 return asList().iterator(); 803 } 804 805 @Override 806 public Spliterator<Entry<K, V>> spliterator() { 807 return asList().spliterator(); 808 } 809 810 @Override 811 public void forEach(Consumer<? super Entry<K, V>> action) { 812 asList().forEach(action); 813 } 814 815 @Override 816 ImmutableList<Entry<K, V>> createAsList() { 817 return new ImmutableAsList<Entry<K, V>>() { 818 @Override 819 public Entry<K, V> get(int index) { 820 return new AbstractMap.SimpleImmutableEntry<>( 821 keySet.asList().get(index), valueList.get(index)); 822 } 823 824 @Override 825 public Spliterator<Entry<K, V>> spliterator() { 826 return CollectSpliterators.indexed( 827 size(), ImmutableSet.SPLITERATOR_CHARACTERISTICS, this::get); 828 } 829 830 @Override 831 ImmutableCollection<Entry<K, V>> delegateCollection() { 832 return EntrySet.this; 833 } 834 }; 835 } 836 837 @Override 838 ImmutableMap<K, V> map() { 839 return ImmutableSortedMap.this; 840 } 841 } 842 return isEmpty() ? ImmutableSet.<Entry<K, V>>of() : new EntrySet(); 843 } 844 845 /** Returns an immutable sorted set of the keys in this map. */ 846 @Override 847 public ImmutableSortedSet<K> keySet() { 848 return keySet; 849 } 850 851 @Override 852 ImmutableSet<K> createKeySet() { 853 throw new AssertionError("should never be called"); 854 } 855 856 /** 857 * Returns an immutable collection of the values in this map, sorted by the ordering of the 858 * corresponding keys. 859 */ 860 @Override 861 public ImmutableCollection<V> values() { 862 return valueList; 863 } 864 865 @Override 866 ImmutableCollection<V> createValues() { 867 throw new AssertionError("should never be called"); 868 } 869 870 /** 871 * Returns the comparator that orders the keys, which is {@link Ordering#natural()} when the 872 * natural ordering of the keys is used. Note that its behavior is not consistent with {@link 873 * TreeMap#comparator()}, which returns {@code null} to indicate natural ordering. 874 */ 875 @Override 876 public Comparator<? super K> comparator() { 877 return keySet().comparator(); 878 } 879 880 @Override 881 public K firstKey() { 882 return keySet().first(); 883 } 884 885 @Override 886 public K lastKey() { 887 return keySet().last(); 888 } 889 890 private ImmutableSortedMap<K, V> getSubMap(int fromIndex, int toIndex) { 891 if (fromIndex == 0 && toIndex == size()) { 892 return this; 893 } else if (fromIndex == toIndex) { 894 return emptyMap(comparator()); 895 } else { 896 return new ImmutableSortedMap<>( 897 keySet.getSubSet(fromIndex, toIndex), valueList.subList(fromIndex, toIndex)); 898 } 899 } 900 901 /** 902 * This method returns a {@code ImmutableSortedMap}, consisting of the entries whose keys are less 903 * than {@code toKey}. 904 * 905 * <p>The {@link SortedMap#headMap} documentation states that a submap of a submap throws an 906 * {@link IllegalArgumentException} if passed a {@code toKey} greater than an earlier {@code 907 * toKey}. However, this method doesn't throw an exception in that situation, but instead keeps 908 * the original {@code toKey}. 909 */ 910 @Override 911 public ImmutableSortedMap<K, V> headMap(K toKey) { 912 return headMap(toKey, false); 913 } 914 915 /** 916 * This method returns a {@code ImmutableSortedMap}, consisting of the entries whose keys are less 917 * than (or equal to, if {@code inclusive}) {@code toKey}. 918 * 919 * <p>The {@link SortedMap#headMap} documentation states that a submap of a submap throws an 920 * {@link IllegalArgumentException} if passed a {@code toKey} greater than an earlier {@code 921 * toKey}. However, this method doesn't throw an exception in that situation, but instead keeps 922 * the original {@code toKey}. 923 * 924 * @since 12.0 925 */ 926 @Override 927 public ImmutableSortedMap<K, V> headMap(K toKey, boolean inclusive) { 928 return getSubMap(0, keySet.headIndex(checkNotNull(toKey), inclusive)); 929 } 930 931 /** 932 * This method returns a {@code ImmutableSortedMap}, consisting of the entries whose keys ranges 933 * from {@code fromKey}, inclusive, to {@code toKey}, exclusive. 934 * 935 * <p>The {@link SortedMap#subMap} documentation states that a submap of a submap throws an {@link 936 * IllegalArgumentException} if passed a {@code fromKey} less than an earlier {@code fromKey}. 937 * However, this method doesn't throw an exception in that situation, but instead keeps the 938 * original {@code fromKey}. Similarly, this method keeps the original {@code toKey}, instead of 939 * throwing an exception, if passed a {@code toKey} greater than an earlier {@code toKey}. 940 */ 941 @Override 942 public ImmutableSortedMap<K, V> subMap(K fromKey, K toKey) { 943 return subMap(fromKey, true, toKey, false); 944 } 945 946 /** 947 * This method returns a {@code ImmutableSortedMap}, consisting of the entries whose keys ranges 948 * from {@code fromKey} to {@code toKey}, inclusive or exclusive as indicated by the boolean 949 * flags. 950 * 951 * <p>The {@link SortedMap#subMap} documentation states that a submap of a submap throws an {@link 952 * IllegalArgumentException} if passed a {@code fromKey} less than an earlier {@code fromKey}. 953 * However, this method doesn't throw an exception in that situation, but instead keeps the 954 * original {@code fromKey}. Similarly, this method keeps the original {@code toKey}, instead of 955 * throwing an exception, if passed a {@code toKey} greater than an earlier {@code toKey}. 956 * 957 * @since 12.0 958 */ 959 @Override 960 public ImmutableSortedMap<K, V> subMap( 961 K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { 962 checkNotNull(fromKey); 963 checkNotNull(toKey); 964 checkArgument( 965 comparator().compare(fromKey, toKey) <= 0, 966 "expected fromKey <= toKey but %s > %s", 967 fromKey, 968 toKey); 969 return headMap(toKey, toInclusive).tailMap(fromKey, fromInclusive); 970 } 971 972 /** 973 * This method returns a {@code ImmutableSortedMap}, consisting of the entries whose keys are 974 * greater than or equals to {@code fromKey}. 975 * 976 * <p>The {@link SortedMap#tailMap} documentation states that a submap of a submap throws an 977 * {@link IllegalArgumentException} if passed a {@code fromKey} less than an earlier {@code 978 * fromKey}. However, this method doesn't throw an exception in that situation, but instead keeps 979 * the original {@code fromKey}. 980 */ 981 @Override 982 public ImmutableSortedMap<K, V> tailMap(K fromKey) { 983 return tailMap(fromKey, true); 984 } 985 986 /** 987 * This method returns a {@code ImmutableSortedMap}, consisting of the entries whose keys are 988 * greater than (or equal to, if {@code inclusive}) {@code fromKey}. 989 * 990 * <p>The {@link SortedMap#tailMap} documentation states that a submap of a submap throws an 991 * {@link IllegalArgumentException} if passed a {@code fromKey} less than an earlier {@code 992 * fromKey}. However, this method doesn't throw an exception in that situation, but instead keeps 993 * the original {@code fromKey}. 994 * 995 * @since 12.0 996 */ 997 @Override 998 public ImmutableSortedMap<K, V> tailMap(K fromKey, boolean inclusive) { 999 return getSubMap(keySet.tailIndex(checkNotNull(fromKey), inclusive), size()); 1000 } 1001 1002 @Override 1003 @CheckForNull 1004 public Entry<K, V> lowerEntry(K key) { 1005 return headMap(key, false).lastEntry(); 1006 } 1007 1008 @Override 1009 @CheckForNull 1010 public K lowerKey(K key) { 1011 return keyOrNull(lowerEntry(key)); 1012 } 1013 1014 @Override 1015 @CheckForNull 1016 public Entry<K, V> floorEntry(K key) { 1017 return headMap(key, true).lastEntry(); 1018 } 1019 1020 @Override 1021 @CheckForNull 1022 public K floorKey(K key) { 1023 return keyOrNull(floorEntry(key)); 1024 } 1025 1026 @Override 1027 @CheckForNull 1028 public Entry<K, V> ceilingEntry(K key) { 1029 return tailMap(key, true).firstEntry(); 1030 } 1031 1032 @Override 1033 @CheckForNull 1034 public K ceilingKey(K key) { 1035 return keyOrNull(ceilingEntry(key)); 1036 } 1037 1038 @Override 1039 @CheckForNull 1040 public Entry<K, V> higherEntry(K key) { 1041 return tailMap(key, false).firstEntry(); 1042 } 1043 1044 @Override 1045 @CheckForNull 1046 public K higherKey(K key) { 1047 return keyOrNull(higherEntry(key)); 1048 } 1049 1050 @Override 1051 @CheckForNull 1052 public Entry<K, V> firstEntry() { 1053 return isEmpty() ? null : entrySet().asList().get(0); 1054 } 1055 1056 @Override 1057 @CheckForNull 1058 public Entry<K, V> lastEntry() { 1059 return isEmpty() ? null : entrySet().asList().get(size() - 1); 1060 } 1061 1062 /** 1063 * Guaranteed to throw an exception and leave the map unmodified. 1064 * 1065 * @throws UnsupportedOperationException always 1066 * @deprecated Unsupported operation. 1067 */ 1068 @CanIgnoreReturnValue 1069 @Deprecated 1070 @Override 1071 @DoNotCall("Always throws UnsupportedOperationException") 1072 @CheckForNull 1073 public final Entry<K, V> pollFirstEntry() { 1074 throw new UnsupportedOperationException(); 1075 } 1076 1077 /** 1078 * Guaranteed to throw an exception and leave the map unmodified. 1079 * 1080 * @throws UnsupportedOperationException always 1081 * @deprecated Unsupported operation. 1082 */ 1083 @CanIgnoreReturnValue 1084 @Deprecated 1085 @Override 1086 @DoNotCall("Always throws UnsupportedOperationException") 1087 @CheckForNull 1088 public final Entry<K, V> pollLastEntry() { 1089 throw new UnsupportedOperationException(); 1090 } 1091 1092 @Override 1093 public ImmutableSortedMap<K, V> descendingMap() { 1094 // TODO(kevinb): the descendingMap is never actually cached at all. Either it should be or the 1095 // code below simplified. 1096 ImmutableSortedMap<K, V> result = descendingMap; 1097 if (result == null) { 1098 if (isEmpty()) { 1099 return result = emptyMap(Ordering.from(comparator()).reverse()); 1100 } else { 1101 return result = 1102 new ImmutableSortedMap<>( 1103 (RegularImmutableSortedSet<K>) keySet.descendingSet(), valueList.reverse(), this); 1104 } 1105 } 1106 return result; 1107 } 1108 1109 @Override 1110 public ImmutableSortedSet<K> navigableKeySet() { 1111 return keySet; 1112 } 1113 1114 @Override 1115 public ImmutableSortedSet<K> descendingKeySet() { 1116 return keySet.descendingSet(); 1117 } 1118 1119 /** 1120 * Serialized type for all ImmutableSortedMap instances. It captures the logical contents and they 1121 * are reconstructed using public factory methods. This ensures that the implementation types 1122 * remain as implementation details. 1123 */ 1124 private static class SerializedForm<K, V> extends ImmutableMap.SerializedForm<K, V> { 1125 private final Comparator<? super K> comparator; 1126 1127 SerializedForm(ImmutableSortedMap<K, V> sortedMap) { 1128 super(sortedMap); 1129 comparator = sortedMap.comparator(); 1130 } 1131 1132 @Override 1133 Builder<K, V> makeBuilder(int size) { 1134 return new Builder<>(comparator); 1135 } 1136 1137 private static final long serialVersionUID = 0; 1138 } 1139 1140 @Override 1141 Object writeReplace() { 1142 return new SerializedForm<>(this); 1143 } 1144 1145 // This class is never actually serialized directly, but we have to make the 1146 // warning go away (and suppressing would suppress for all nested classes too) 1147 private static final long serialVersionUID = 0; 1148}