code: 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);
    }
docs: 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