diff options
Diffstat (limited to 'android/guava/src/com/google/common/collect/Comparators.java')
-rw-r--r-- | android/guava/src/com/google/common/collect/Comparators.java | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/android/guava/src/com/google/common/collect/Comparators.java b/android/guava/src/com/google/common/collect/Comparators.java index 0c79a8c29..7ada5e538 100644 --- a/android/guava/src/com/google/common/collect/Comparators.java +++ b/android/guava/src/com/google/common/collect/Comparators.java @@ -17,10 +17,13 @@ package com.google.common.collect; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.CollectPreconditions.checkNonnegative; import com.google.common.annotations.GwtCompatible; import java.util.Comparator; import java.util.Iterator; +import java.util.List; +import java.util.stream.Collector; import org.checkerframework.checker.nullness.qual.Nullable; /** @@ -107,6 +110,65 @@ public final class Comparators { } /** + * Returns a {@code Collector} that returns the {@code k} smallest (relative to the specified + * {@code Comparator}) input elements, in ascending order, as an unmodifiable {@code List}. Ties + * are broken arbitrarily. + * + * <p>For example: + * + * <pre>{@code + * Stream.of("foo", "quux", "banana", "elephant") + * .collect(least(2, comparingInt(String::length))) + * // returns {"foo", "quux"} + * }</pre> + * + * <p>This {@code Collector} uses O(k) memory and takes expected time O(n) (worst-case O(n log + * k)), as opposed to e.g. {@code Stream.sorted(comparator).limit(k)}, which currently takes O(n + * log n) time and O(n) space. + * + * @throws IllegalArgumentException if {@code k < 0} + */ + @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( + int k, Comparator<? super T> comparator) { + checkNonnegative(k, "k"); + checkNotNull(comparator); + return Collector.of( + () -> TopKSelector.<T>least(k, comparator), + TopKSelector::offer, + TopKSelector::combine, + TopKSelector::topK, + Collector.Characteristics.UNORDERED); + } + + /** + * Returns a {@code Collector} that returns the {@code k} greatest (relative to the specified + * {@code Comparator}) input elements, in descending order, as an unmodifiable {@code List}. Ties + * are broken arbitrarily. + * + * <p>For example: + * + * <pre>{@code + * Stream.of("foo", "quux", "banana", "elephant") + * .collect(greatest(2, comparingInt(String::length))) + * // returns {"elephant", "banana"} + * }</pre> + * + * <p>This {@code Collector} uses O(k) memory and takes expected time O(n) (worst-case O(n log + * k)), as opposed to e.g. {@code Stream.sorted(comparator.reversed()).limit(k)}, which currently + * takes O(n log n) time and O(n) space. + * + * @throws IllegalArgumentException if {@code k < 0} + */ + @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( + int k, Comparator<? super T> comparator) { + return least(k, comparator.reversed()); + } + + /** * Returns the minimum of the two values. If the values compare as 0, the first is returned. * * <p>The recommended solution for finding the {@code minimum} of some values depends on the type |