Skip to content

Commit

Permalink
Introduce ImmutableMap.Builder.buildOrThrow().
Browse files Browse the repository at this point in the history
This new method is equivalent to the existing `ImmutableMap.Builder.build()`. `build()` now just calls `buildOrThrow()` and will soon be deprecated. The idea is to make it more obvious that duplicate keys will cause an exception.

Make similar changes to the builders of `ImmutableBiMap`, `ImmutableSortedMap`, and `ImmutableTable`.

RELNOTES=The method `ImmutableMap.Builder.build()` is now renamed to `buildOrThrow()`. The existing `build()` method will continue to exist but will be deprecated and the new name should be used in new code.
PiperOrigin-RevId: 396865988
  • Loading branch information
eamonnmcmanus authored and Google Java Core Libraries committed Sep 15, 2021
1 parent cd3b419 commit 4bbe12c
Show file tree
Hide file tree
Showing 11 changed files with 167 additions and 27 deletions.
23 changes: 20 additions & 3 deletions android/guava/src/com/google/common/collect/ImmutableBiMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ public static <K, V> Builder<K, V> builderWithExpectedSize(int expectedSize) {
* .put("one", 1)
* .put("two", 2)
* .put("three", 3)
* .build();
* .buildOrThrow();
* }</pre>
*
* <p>For <i>small</i> immutable bimaps, the {@code ImmutableBiMap.of()} methods are even more
Expand All @@ -323,8 +323,8 @@ public static <K, V> Builder<K, V> builderWithExpectedSize(int expectedSize) {
* want a different order, consider using {@link #orderEntriesByValue(Comparator)}, which changes
* this builder to sort entries by value.
*
* <p>Builder instances can be reused - it is safe to call {@link #build} multiple times to build
* multiple bimaps in series. Each bimap is a superset of the bimaps created before it.
* <p>Builder instances can be reused - it is safe to call {@link #buildOrThrow} multiple times to
* build multiple bimaps in series. Each bimap is a superset of the bimaps created before it.
*
* @since 2.0
*/
Expand Down Expand Up @@ -423,10 +423,27 @@ Builder<K, V> combine(ImmutableMap.Builder<K, V> builder) {
* order in which entries were inserted into the builder, unless {@link #orderEntriesByValue}
* was called, in which case entries are sorted by value.
*
* <p>Prefer the equivalent method {@link #buildOrThrow()} to make it explicit that the method
* will throw an exception if there are duplicate keys or values. The {@code build()} method
* will soon be deprecated.
*
* @throws IllegalArgumentException if duplicate keys or values were added
*/
@Override
public ImmutableBiMap<K, V> build() {
return buildOrThrow();
}

/**
* Returns a newly-created immutable bimap, or throws an exception if any key or value was added
* more than once. The iteration order of the returned bimap is the order in which entries were
* inserted into the builder, unless {@link #orderEntriesByValue} was called, in which case
* entries are sorted by value.
*
* @throws IllegalArgumentException if duplicate keys or values were added
*/
@Override
public ImmutableBiMap<K, V> buildOrThrow() {
if (size == 0) {
return of();
}
Expand Down
24 changes: 20 additions & 4 deletions android/guava/src/com/google/common/collect/ImmutableMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ static IllegalArgumentException conflictException(
* .put("one", 1)
* .put("two", 2)
* .put("three", 3)
* .build();
* .buildOrThrow();
* }</pre>
*
* <p>For <i>small</i> immutable maps, the {@code ImmutableMap.of()} methods are even more
Expand All @@ -373,8 +373,8 @@ static IllegalArgumentException conflictException(
* sort by keys, or call {@link #orderEntriesByValue(Comparator)}, which changes this builder to
* sort entries by value.
*
* <p>Builder instances can be reused - it is safe to call {@link #build} multiple times to build
* multiple maps in series. Each map is a superset of the maps created before it.
* <p>Builder instances can be reused - it is safe to call {@link #buildOrThrow} multiple times to
* build multiple maps in series. Each map is a superset of the maps created before it.
*
* @since 2.0
*/
Expand Down Expand Up @@ -508,10 +508,26 @@ Builder<K, V> combine(Builder<K, V> other) {
* in which entries were inserted into the builder, unless {@link #orderEntriesByValue} was
* called, in which case entries are sorted by value.
*
* <p>Prefer the equivalent method {@link #buildOrThrow()} to make it explicit that the method
* will throw an exception if there are duplicate keys. The {@code build()} method will soon be
* deprecated.
*
* @throws IllegalArgumentException if duplicate keys were added
*/
@SuppressWarnings("unchecked")
public ImmutableMap<K, V> build() {
return buildOrThrow();
}

/**
* Returns a newly-created immutable map, or throws an exception if any key was added more than
* once. The iteration order of the returned map is the order in which entries were inserted
* into the builder, unless {@link #orderEntriesByValue} was called, in which case entries are
* sorted by value.
*
* @throws IllegalArgumentException if duplicate keys were added
*/
@SuppressWarnings("unchecked")
public ImmutableMap<K, V> buildOrThrow() {
/*
* If entries is full, then this implementation may end up using the entries array
* directly and writing over the entry objects with non-terminal entries, but this is
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -560,14 +560,14 @@ public static <K extends Comparable<?>, V> Builder<K, V> reverseOrder() {
* .put(1, "one")
* .put(2, "two")
* .put(3, "three")
* .build();
* .buildOrThrow();
* }</pre>
*
* <p>For <i>small</i> immutable sorted maps, the {@code ImmutableSortedMap.of()} methods are even
* more convenient.
*
* <p>Builder instances can be reused - it is safe to call {@link #build} multiple times to build
* multiple maps in series. Each map is a superset of the maps created before it.
* <p>Builder instances can be reused - it is safe to call {@link #buildOrThrow} multiple times to
* build multiple maps in series. Each map is a superset of the maps created before it.
*
* @since 2.0
*/
Expand Down Expand Up @@ -686,11 +686,27 @@ Builder<K, V> combine(ImmutableSortedMap.Builder<K, V> other) {
/**
* Returns a newly-created immutable sorted map.
*
* <p>Prefer the equivalent method {@link #buildOrThrow()} to make it explicit that the method
* will throw an exception if there are duplicate keys. The {@code build()} method will soon be
* deprecated.
*
* @throws IllegalArgumentException if any two keys are equal according to the comparator (which
* might be the keys' natural order)
*/
@Override
public ImmutableSortedMap<K, V> build() {
return buildOrThrow();
}

/**
* Returns a newly-created immutable sorted map, or throws an exception if any two keys are
* equal.
*
* @throws IllegalArgumentException if any two keys are equal according to the comparator (which
* might be the keys' natural order)
*/
@Override
public ImmutableSortedMap<K, V> buildOrThrow() {
switch (size) {
case 0:
return emptyMap(comparator);
Expand Down
20 changes: 17 additions & 3 deletions android/guava/src/com/google/common/collect/ImmutableTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ static <R, C, V> Cell<R, C, V> cellOf(R rowKey, C columnKey, V value) {
* .put(1, 'A', "foo")
* .put(1, 'B', "bar")
* .put(2, 'A', "baz")
* .build();
* .buildOrThrow();
* }</pre>
*
* <p>By default, the order in which cells are added to the builder determines the iteration
Expand All @@ -133,8 +133,8 @@ static <R, C, V> Cell<R, C, V> cellOf(R rowKey, C columnKey, V value) {
* <p>For empty or single-cell immutable tables, {@link #of()} and {@link #of(Object, Object,
* Object)} are even more convenient.
*
* <p>Builder instances can be reused - it is safe to call {@link #build} multiple times to build
* multiple tables in series. Each table is a superset of the tables created before it.
* <p>Builder instances can be reused - it is safe to call {@link #buildOrThrow} multiple times to
* build multiple tables in series. Each table is a superset of the tables created before it.
*
* @since 11.0
*/
Expand Down Expand Up @@ -216,9 +216,23 @@ Builder<R, C, V> combine(Builder<R, C, V> other) {
/**
* Returns a newly-created immutable table.
*
* <p>Prefer the equivalent method {@link #buildOrThrow()} to make it explicit that the method
* will throw an exception if there are duplicate key pairs. The {@code build()} method will
* soon be deprecated.
*
* @throws IllegalArgumentException if duplicate key pairs were added
*/
public ImmutableTable<R, C, V> build() {
return buildOrThrow();
}

/**
* Returns a newly-created immutable table, or throws an exception if duplicate key pairs were
* added.
*
* @throws IllegalArgumentException if duplicate key pairs were added
*/
public ImmutableTable<R, C, V> buildOrThrow() {
int size = cells.size();
switch (size) {
case 0:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,16 @@ Builder<K, V> combine(Builder<K, V> other) {

@Override
public ImmutableBiMap<K, V> build() {
ImmutableMap<K, V> map = super.build();
return buildOrThrow();
}

@Override
public ImmutableBiMap<K, V> buildOrThrow() {
ImmutableMap<K, V> map = super.buildOrThrow();
if (map.isEmpty()) {
return of();
}
return new RegularImmutableBiMap<K, V>(super.build());
return new RegularImmutableBiMap<K, V>(super.buildOrThrow());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,10 @@ Builder<K, V> combine(Builder<K, V> other) {
}

public ImmutableMap<K, V> build() {
return buildOrThrow();
}

public ImmutableMap<K, V> buildOrThrow() {
if (valueComparator != null) {
Collections.sort(
entries, Ordering.from(valueComparator).onResultOf(Maps.<V>valueFunction()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,11 @@ public Builder<K, V> orderEntriesByValue(Comparator<? super V> valueComparator)

@Override
public ImmutableSortedMap<K, V> build() {
return buildOrThrow();
}

@Override
public ImmutableSortedMap<K, V> buildOrThrow() {
SortedMap<K, V> delegate = newModifiableDelegate(comparator);
for (Entry<? extends K, ? extends V> entry : entries) {
putEntryWithChecks(delegate, entry);
Expand Down
23 changes: 20 additions & 3 deletions guava/src/com/google/common/collect/ImmutableBiMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ public static <K, V> Builder<K, V> builderWithExpectedSize(int expectedSize) {
* .put("one", 1)
* .put("two", 2)
* .put("three", 3)
* .build();
* .buildOrThrow();
* }</pre>
*
* <p>For <i>small</i> immutable bimaps, the {@code ImmutableBiMap.of()} methods are even more
Expand All @@ -329,8 +329,8 @@ public static <K, V> Builder<K, V> builderWithExpectedSize(int expectedSize) {
* want a different order, consider using {@link #orderEntriesByValue(Comparator)}, which changes
* this builder to sort entries by value.
*
* <p>Builder instances can be reused - it is safe to call {@link #build} multiple times to build
* multiple bimaps in series. Each bimap is a superset of the bimaps created before it.
* <p>Builder instances can be reused - it is safe to call {@link #buildOrThrow} multiple times to
* build multiple bimaps in series. Each bimap is a superset of the bimaps created before it.
*
* @since 2.0
*/
Expand Down Expand Up @@ -428,10 +428,27 @@ Builder<K, V> combine(ImmutableMap.Builder<K, V> builder) {
* order in which entries were inserted into the builder, unless {@link #orderEntriesByValue}
* was called, in which case entries are sorted by value.
*
* <p>Prefer the equivalent method {@link #buildOrThrow()} to make it explicit that the method
* will throw an exception if there are duplicate keys or values. The {@code build()} method
* will soon be deprecated.
*
* @throws IllegalArgumentException if duplicate keys or values were added
*/
@Override
public ImmutableBiMap<K, V> build() {
return buildOrThrow();
}

/**
* Returns a newly-created immutable bimap, or throws an exception if any key or value was added
* more than once. The iteration order of the returned bimap is the order in which entries were
* inserted into the builder, unless {@link #orderEntriesByValue} was called, in which case
* entries are sorted by value.
*
* @throws IllegalArgumentException if duplicate keys or values were added
*/
@Override
public ImmutableBiMap<K, V> buildOrThrow() {
switch (size) {
case 0:
return of();
Expand Down
22 changes: 19 additions & 3 deletions guava/src/com/google/common/collect/ImmutableMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ static IllegalArgumentException conflictException(
* .put("one", 1)
* .put("two", 2)
* .put("three", 3)
* .build();
* .buildOrThrow();
* }</pre>
*
* <p>For <i>small</i> immutable maps, the {@code ImmutableMap.of()} methods are even more
Expand All @@ -401,8 +401,8 @@ static IllegalArgumentException conflictException(
* sort by keys, or call {@link #orderEntriesByValue(Comparator)}, which changes this builder to
* sort entries by value.
*
* <p>Builder instances can be reused - it is safe to call {@link #build} multiple times to build
* multiple maps in series. Each map is a superset of the maps created before it.
* <p>Builder instances can be reused - it is safe to call {@link #buildOrThrow} multiple times to
* build multiple maps in series. Each map is a superset of the maps created before it.
*
* @since 2.0
*/
Expand Down Expand Up @@ -528,9 +528,25 @@ Builder<K, V> combine(Builder<K, V> other) {
* in which entries were inserted into the builder, unless {@link #orderEntriesByValue} was
* called, in which case entries are sorted by value.
*
* <p>Prefer the equivalent method {@link #buildOrThrow()} to make it explicit that the method
* will throw an exception if there are duplicate keys. The {@code build()} method will soon be
* deprecated.
*
* @throws IllegalArgumentException if duplicate keys were added
*/
public ImmutableMap<K, V> build() {
return buildOrThrow();
}

/**
* Returns a newly-created immutable map, or throws an exception if any key was added more than
* once. The iteration order of the returned map is the order in which entries were inserted
* into the builder, unless {@link #orderEntriesByValue} was called, in which case entries are
* sorted by value.
*
* @throws IllegalArgumentException if duplicate keys were added
*/
public ImmutableMap<K, V> buildOrThrow() {
/*
* If entries is full, or if hash flooding is detected, then this implementation may end up
* using the entries array directly and writing over the entry objects with non-terminal
Expand Down
22 changes: 19 additions & 3 deletions guava/src/com/google/common/collect/ImmutableSortedMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -607,14 +607,14 @@ public static <K extends Comparable<?>, V> Builder<K, V> reverseOrder() {
* .put(1, "one")
* .put(2, "two")
* .put(3, "three")
* .build();
* .buildOrThrow();
* }</pre>
*
* <p>For <i>small</i> immutable sorted maps, the {@code ImmutableSortedMap.of()} methods are even
* more convenient.
*
* <p>Builder instances can be reused - it is safe to call {@link #build} multiple times to build
* multiple maps in series. Each map is a superset of the maps created before it.
* <p>Builder instances can be reused - it is safe to call {@link #buildOrThrow} multiple times to
* build multiple maps in series. Each map is a superset of the maps created before it.
*
* @since 2.0
*/
Expand Down Expand Up @@ -710,11 +710,27 @@ Builder<K, V> combine(ImmutableMap.Builder<K, V> other) {
/**
* Returns a newly-created immutable sorted map.
*
* <p>Prefer the equivalent method {@link #buildOrThrow()} to make it explicit that the method
* will throw an exception if there are duplicate keys. The {@code build()} method will soon be
* deprecated.
*
* @throws IllegalArgumentException if any two keys are equal according to the comparator (which
* might be the keys' natural order)
*/
@Override
public ImmutableSortedMap<K, V> build() {
return buildOrThrow();
}

/**
* Returns a newly-created immutable sorted map, or throws an exception if any two keys are
* equal.
*
* @throws IllegalArgumentException if any two keys are equal according to the comparator (which
* might be the keys' natural order)
*/
@Override
public ImmutableSortedMap<K, V> buildOrThrow() {
switch (size) {
case 0:
return emptyMap(comparator);
Expand Down
Loading

0 comments on commit 4bbe12c

Please sign in to comment.