Skip to content

Commit

Permalink
Make our Collector APIs available in guava-android.
Browse files Browse the repository at this point in the history
(for example, `ImmutableList.toImmutableList()`)

For now, we're making them `@Beta` just in case users encounter enough problems that we find it less disruptive to revert this change than to keep it. However, we plan to remove `@Beta` soon, at which point we'll be committed to this APIs. If you use Guava under Android, please [test with Guava 33.0.0 or higher](https://groups.google.com/g/guava-announce/c/9-dw_C6G_NM), ideally with 34.0.0 or higher (which will contain this commit), and [report any problems](https://github.com/google/guava/issues/new?assignees=&labels=type%3Ddefect&projects=&template=bug_report.yaml).

Our expectation is that this commit should not cause problems, even for users who don't use enable [library desugaring](https://developer.android.com/studio/write/java11-default-support-table). But we will see what happens in wild.

Of course, if you want to actually _use_ these APIs, then you'll need to [enable library desugaring](https://developer.android.com/studio/write/java8-support#library-desugaring) or target a [new enough version of Android](https://developer.android.com/reference/java/util/stream/Stream), just as with any other `Stream`-based APIs.

(progress toward #6567)

RELNOTES=`collect`: Made our `Collector` APIs (e.g., `ImmutableList.toImmutableList()`) available in `guava-android`.
PiperOrigin-RevId: 629191336
  • Loading branch information
cpovirk authored and Google Java Core Libraries committed Apr 30, 2024
1 parent fddc95d commit 876873c
Show file tree
Hide file tree
Showing 20 changed files with 192 additions and 57 deletions.
9 changes: 7 additions & 2 deletions android/guava/src/com/google/common/collect/Comparators.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.CollectPreconditions.checkNonnegative;

import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import java.util.Comparator;
import java.util.Iterator;
Expand Down Expand Up @@ -127,10 +128,12 @@ private Comparators() {}
* log n) time and O(n) space.
*
* @throws IllegalArgumentException if {@code k < 0}
* @since NEXT (available since 22.0 in guava-jre)
*/
@SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"})
@IgnoreJRERequirement // Users will use this only if they're already using streams.
static <T extends @Nullable Object> Collector<T, ?, List<T>> least(
@Beta // TODO: b/288085449 - Remove.
public static <T extends @Nullable Object> Collector<T, ?, List<T>> least(
int k, Comparator<? super T> comparator) {
checkNonnegative(k, "k");
checkNotNull(comparator);
Expand Down Expand Up @@ -160,10 +163,12 @@ private Comparators() {}
* takes O(n log n) time and O(n) space.
*
* @throws IllegalArgumentException if {@code k < 0}
* @since NEXT (available since 22.0 in guava-jre)
*/
@SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"})
@IgnoreJRERequirement // Users will use this only if they're already using streams.
static <T extends @Nullable Object> Collector<T, ?, List<T>> greatest(
@Beta // TODO: b/288085449 - Remove.
public static <T extends @Nullable Object> Collector<T, ?, List<T>> greatest(
int k, Comparator<? super T> comparator) {
return least(k, comparator.reversed());
}
Expand Down
31 changes: 21 additions & 10 deletions android/guava/src/com/google/common/collect/ImmutableBiMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static com.google.common.collect.CollectPreconditions.checkEntryNotNull;
import static com.google.common.collect.CollectPreconditions.checkNonnegative;

import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.J2ktIncompatible;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
Expand Down Expand Up @@ -56,12 +57,16 @@ public abstract class ImmutableBiMap<K, V> extends ImmutableMap<K, V> implements
* Object#equals(Object)}), an {@code IllegalArgumentException} is thrown when the collection
* operation is performed. (This differs from the {@code Collector} returned by {@link
* Collectors#toMap(Function, Function)}, which throws an {@code IllegalStateException}.)
*
* @since NEXT (available since 21.0 in guava-jre)
*/
@SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"})
@IgnoreJRERequirement // Users will use this only if they're already using streams.
static <T extends @Nullable Object, K, V> Collector<T, ?, ImmutableBiMap<K, V>> toImmutableBiMap(
Function<? super T, ? extends K> keyFunction,
Function<? super T, ? extends V> valueFunction) {
@Beta // TODO: b/288085449 - Remove.
public static <T extends @Nullable Object, K, V>
Collector<T, ?, ImmutableBiMap<K, V>> toImmutableBiMap(
Function<? super T, ? extends K> keyFunction,
Function<? super T, ? extends V> valueFunction) {
return CollectCollectors.toImmutableBiMap(keyFunction, valueFunction);
}

Expand Down Expand Up @@ -621,14 +626,17 @@ private void readObject(ObjectInputStream stream) throws InvalidObjectException
*
* @throws UnsupportedOperationException always
* @deprecated Use {@link ImmutableBiMap#toImmutableBiMap}.
* @since NEXT (available since 21.0 in guava-jre)
*/
@Deprecated
@DoNotCall("Use toImmutableBiMap")
@SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"})
@IgnoreJRERequirement // Users will use this only if they're already using streams.
static <T extends @Nullable Object, K, V> Collector<T, ?, ImmutableMap<K, V>> toImmutableMap(
Function<? super T, ? extends K> keyFunction,
Function<? super T, ? extends V> valueFunction) {
@Beta // TODO: b/288085449 - Remove.
public static <T extends @Nullable Object, K, V>
Collector<T, ?, ImmutableMap<K, V>> toImmutableMap(
Function<? super T, ? extends K> keyFunction,
Function<? super T, ? extends V> valueFunction) {
throw new UnsupportedOperationException();
}

Expand All @@ -639,15 +647,18 @@ private void readObject(ObjectInputStream stream) throws InvalidObjectException
*
* @throws UnsupportedOperationException always
* @deprecated
* @since NEXT (available since 21.0 in guava-jre)
*/
@Deprecated
@DoNotCall("Use toImmutableBiMap")
@SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"})
@IgnoreJRERequirement // Users will use this only if they're already using streams.
static <T extends @Nullable Object, K, V> Collector<T, ?, ImmutableMap<K, V>> toImmutableMap(
Function<? super T, ? extends K> keyFunction,
Function<? super T, ? extends V> valueFunction,
BinaryOperator<V> mergeFunction) {
@Beta // TODO: b/288085449 - Remove.
public static <T extends @Nullable Object, K, V>
Collector<T, ?, ImmutableMap<K, V>> toImmutableMap(
Function<? super T, ? extends K> keyFunction,
Function<? super T, ? extends V> valueFunction,
BinaryOperator<V> mergeFunction) {
throw new UnsupportedOperationException();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import static com.google.common.collect.ObjectArrays.checkElementsNotNull;
import static com.google.common.collect.RegularImmutableList.EMPTY;

import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.annotations.J2ktIncompatible;
Expand Down Expand Up @@ -66,10 +67,13 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
/**
* Returns a {@code Collector} that accumulates the input elements into a new {@code
* ImmutableList}, in encounter order.
*
* @since NEXT (available since 21.0 in guava-jre)
*/
@SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"})
@IgnoreJRERequirement // Users will use this only if they're already using streams.
static <E> Collector<E, ?, ImmutableList<E>> toImmutableList() {
@Beta // TODO: b/288085449 - Remove.
public static <E> Collector<E, ?, ImmutableList<E>> toImmutableList() {
return CollectCollectors.toImmutableList();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import static java.util.Objects.requireNonNull;

import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.annotations.J2ktIncompatible;
Expand Down Expand Up @@ -78,10 +79,13 @@ public class ImmutableListMultimap<K, V> extends ImmutableMultimap<K, V>
* .putAll('c', "arrot", "herry")
* .build();
* }</pre>
*
* @since NEXT (available since 21.0 in guava-jre)
*/
@SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"})
@IgnoreJRERequirement // Users will use this only if they're already using streams.
static <T extends @Nullable Object, K, V>
@Beta // TODO: b/288085449 - Remove.
public static <T extends @Nullable Object, K, V>
Collector<T, ?, ImmutableListMultimap<K, V>> toImmutableListMultimap(
Function<? super T, ? extends K> keyFunction,
Function<? super T, ? extends V> valueFunction) {
Expand Down Expand Up @@ -116,10 +120,13 @@ public class ImmutableListMultimap<K, V> extends ImmutableMultimap<K, V>
* .build();
* }
* }</pre>
*
* @since NEXT (available since 21.0 in guava-jre)
*/
@SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"})
@IgnoreJRERequirement // Users will use this only if they're already using streams.
static <T extends @Nullable Object, K, V>
@Beta // TODO: b/288085449 - Remove.
public static <T extends @Nullable Object, K, V>
Collector<T, ?, ImmutableListMultimap<K, V>> flatteningToImmutableListMultimap(
Function<? super T, ? extends K> keyFunction,
Function<? super T, ? extends Stream<? extends V>> valuesFunction) {
Expand Down
23 changes: 16 additions & 7 deletions android/guava/src/com/google/common/collect/ImmutableMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import static com.google.common.collect.CollectPreconditions.checkNonnegative;
import static java.util.Objects.requireNonNull;

import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.annotations.J2ktIncompatible;
Expand Down Expand Up @@ -79,12 +80,16 @@ public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
* IllegalArgumentException} is thrown when the collection operation is performed. (This differs
* from the {@code Collector} returned by {@link Collectors#toMap(Function, Function)}, which
* throws an {@code IllegalStateException}.)
*
* @since NEXT (available since 21.0 in guava-jre)
*/
@SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"})
@IgnoreJRERequirement // Users will use this only if they're already using streams.
static <T extends @Nullable Object, K, V> Collector<T, ?, ImmutableMap<K, V>> toImmutableMap(
Function<? super T, ? extends K> keyFunction,
Function<? super T, ? extends V> valueFunction) {
@Beta // TODO: b/288085449 - Remove.
public static <T extends @Nullable Object, K, V>
Collector<T, ?, ImmutableMap<K, V>> toImmutableMap(
Function<? super T, ? extends K> keyFunction,
Function<? super T, ? extends V> valueFunction) {
return CollectCollectors.toImmutableMap(keyFunction, valueFunction);
}

Expand All @@ -98,13 +103,17 @@ public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
* future occurrences of the key would reinsert it).
*
* <p>Entries will appear in the encounter order of the first occurrence of the key.
*
* @since NEXT (available since 21.0 in guava-jre)
*/
@SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"})
@IgnoreJRERequirement // Users will use this only if they're already using streams.
static <T extends @Nullable Object, K, V> Collector<T, ?, ImmutableMap<K, V>> toImmutableMap(
Function<? super T, ? extends K> keyFunction,
Function<? super T, ? extends V> valueFunction,
BinaryOperator<V> mergeFunction) {
@Beta // TODO: b/288085449 - Remove.
public static <T extends @Nullable Object, K, V>
Collector<T, ?, ImmutableMap<K, V>> toImmutableMap(
Function<? super T, ? extends K> keyFunction,
Function<? super T, ? extends V> valueFunction,
BinaryOperator<V> mergeFunction) {
return CollectCollectors.toImmutableMap(keyFunction, valueFunction, mergeFunction);
}

Expand Down
15 changes: 12 additions & 3 deletions android/guava/src/com/google/common/collect/ImmutableMultiset.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.Objects.requireNonNull;

import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.annotations.J2ktIncompatible;
Expand Down Expand Up @@ -64,10 +65,13 @@ public abstract class ImmutableMultiset<E> extends ImmutableMultisetGwtSerializa
* Returns a {@code Collector} that accumulates the input elements into a new {@code
* ImmutableMultiset}. Elements iterate in order by the <i>first</i> appearance of that element in
* encounter order.
*
* @since NEXT (available since 21.0 in guava-jre)
*/
@SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"})
@IgnoreJRERequirement // Users will use this only if they're already using streams.
static <E> Collector<E, ?, ImmutableMultiset<E>> toImmutableMultiset() {
@Beta // TODO: b/288085449 - Remove.
public static <E> Collector<E, ?, ImmutableMultiset<E>> toImmutableMultiset() {
return CollectCollectors.toImmutableMultiset(Function.identity(), e -> 1);
}

Expand All @@ -79,11 +83,16 @@ public abstract class ImmutableMultiset<E> extends ImmutableMultisetGwtSerializa
* <p>If the mapped elements contain duplicates (according to {@link Object#equals}), the first
* occurrence in encounter order appears in the resulting multiset, with count equal to the sum of
* the outputs of {@code countFunction.applyAsInt(t)} for each {@code t} mapped to that element.
*
* @since NEXT (available since 22.0 in guava-jre)
*/
@SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"})
@IgnoreJRERequirement // Users will use this only if they're already using streams.
static <T extends @Nullable Object, E> Collector<T, ?, ImmutableMultiset<E>> toImmutableMultiset(
Function<? super T, ? extends E> elementFunction, ToIntFunction<? super T> countFunction) {
@Beta // TODO: b/288085449 - Remove.
public static <T extends @Nullable Object, E>
Collector<T, ?, ImmutableMultiset<E>> toImmutableMultiset(
Function<? super T, ? extends E> elementFunction,
ToIntFunction<? super T> countFunction) {
return CollectCollectors.toImmutableMultiset(elementFunction, countFunction);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static com.google.common.base.Preconditions.checkElementIndex;
import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.annotations.J2ktIncompatible;
import com.google.common.collect.SortedLists.KeyAbsentBehavior;
Expand Down Expand Up @@ -55,10 +56,13 @@ public class ImmutableRangeMap<K extends Comparable<?>, V> implements RangeMap<K
/**
* Returns a {@code Collector} that accumulates the input elements into a new {@code
* ImmutableRangeMap}. As in {@link Builder}, overlapping ranges are not permitted.
*
* @since NEXT (available since 23.1 in guava-jre)
*/
@SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"})
@IgnoreJRERequirement // Users will use this only if they're already using streams.
static <T extends @Nullable Object, K extends Comparable<? super K>, V>
@Beta // TODO: b/288085449 - Remove.
public static <T extends @Nullable Object, K extends Comparable<? super K>, V>
Collector<T, ?, ImmutableRangeMap<K, V>> toImmutableRangeMap(
Function<? super T, Range<K>> keyFunction,
Function<? super T, ? extends V> valueFunction) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import static com.google.common.collect.SortedLists.KeyPresentBehavior.ANY_PRESENT;
import static java.util.Objects.requireNonNull;

import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.annotations.J2ktIncompatible;
import com.google.common.collect.SortedLists.KeyAbsentBehavior;
Expand Down Expand Up @@ -64,10 +65,13 @@ public final class ImmutableRangeSet<C extends Comparable> extends AbstractRange
* Returns a {@code Collector} that accumulates the input elements into a new {@code
* ImmutableRangeSet}. As in {@link Builder}, overlapping ranges are not permitted and adjacent
* ranges will be merged.
*
* @since NEXT (available since 23.1 in guava-jre)
*/
@SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"})
@IgnoreJRERequirement // Users will use this only if they're already using streams.
static <E extends Comparable<? super E>>
@Beta // TODO: b/288085449 - Remove.
public static <E extends Comparable<? super E>>
Collector<Range<E>, ?, ImmutableRangeSet<E>> toImmutableRangeSet() {
return CollectCollectors.toImmutableRangeSet();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import static com.google.common.collect.ObjectArrays.checkElementNotNull;
import static java.util.Objects.requireNonNull;

import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.J2ktIncompatible;
import com.google.common.annotations.VisibleForTesting;
Expand Down Expand Up @@ -58,10 +59,13 @@ public abstract class ImmutableSet<E> extends ImmutableCollection<E> implements
* ImmutableSet}. Elements appear in the resulting set in the encounter order of the stream; if
* the stream contains duplicates (according to {@link Object#equals(Object)}), only the first
* duplicate in encounter order will appear in the result.
*
* @since NEXT (available since 21.0 in guava-jre)
*/
@SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"})
@IgnoreJRERequirement // Users will use this only if they're already using streams.
static <E> Collector<E, ?, ImmutableSet<E>> toImmutableSet() {
@Beta // TODO: b/288085449 - Remove.
public static <E> Collector<E, ?, ImmutableSet<E>> toImmutableSet() {
return CollectCollectors.toImmutableSet();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.Objects.requireNonNull;

import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.annotations.J2ktIncompatible;
Expand Down Expand Up @@ -86,10 +87,13 @@ public class ImmutableSetMultimap<K, V> extends ImmutableMultimap<K, V>
* .putAll('c', "arrot", "herry")
* .build();
* }</pre>
*
* @since NEXT (available since 21.0 in guava-jre)
*/
@SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"})
@IgnoreJRERequirement // Users will use this only if they're already using streams.
static <T extends @Nullable Object, K, V>
@Beta // TODO: b/288085449 - Remove.
public static <T extends @Nullable Object, K, V>
Collector<T, ?, ImmutableSetMultimap<K, V>> toImmutableSetMultimap(
Function<? super T, ? extends K> keyFunction,
Function<? super T, ? extends V> valueFunction) {
Expand Down Expand Up @@ -133,10 +137,13 @@ public class ImmutableSetMultimap<K, V> extends ImmutableMultimap<K, V>
* .build();
* }
* }</pre>
*
* @since NEXT (available since 21.0 in guava-jre)
*/
@SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"})
@IgnoreJRERequirement // Users will use this only if they're already using streams.
static <T extends @Nullable Object, K, V>
@Beta // TODO: b/288085449 - Remove.
public static <T extends @Nullable Object, K, V>
Collector<T, ?, ImmutableSetMultimap<K, V>> flatteningToImmutableSetMultimap(
Function<? super T, ? extends K> keyFunction,
Function<? super T, ? extends Stream<? extends V>> valuesFunction) {
Expand Down

0 comments on commit 876873c

Please sign in to comment.