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