guava/src/com/google/common/collect/Comparators.java
public static <T> 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);
  }
public static <T> 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);
  }
public static < T > 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} 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}
@since 22.0
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 .