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: 629491350
  • Loading branch information
cpovirk authored and Google Java Core Libraries committed Apr 30, 2024
1 parent fddc95d commit 96fca0b
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
Loading

1 comment on commit 96fca0b

@cpovirk
Copy link
Member Author

@cpovirk cpovirk commented on 96fca0b May 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ideally with 34.0.0 or higher

Sorry, that will be 33.2.0, not 34.0.0.

Please sign in to comment.