guava/src/com/google/common/collect/Multisets.java
public static <T, E, M extends Multiset<E>> Collector<T, ?, M> toMultiset(
      java.util.function.Function<? super T, E> elementFunction,
      java.util.function.ToIntFunction<? super T> countFunction,
      java.util.function.Supplier<M> multisetSupplier) {
    checkNotNull(elementFunction);
    checkNotNull(countFunction);
    checkNotNull(multisetSupplier);
    return Collector.of(
        multisetSupplier,
        (ms, t) -> ms.add(elementFunction.apply(t), countFunction.applyAsInt(t)),
        (ms1, ms2) -> {
          ms1.addAll(ms2);
          return ms1;
        });
  }
public static <T, E, M extends Multiset<E>> Collector<T, ?, M> toMultiset(
      java.util.function.Function<? super T, E> elementFunction,
      java.util.function.ToIntFunction<? super T> countFunction,
      java.util.function.Supplier<M> multisetSupplier) {
    checkNotNull(elementFunction);
    checkNotNull(countFunction);
    checkNotNull(multisetSupplier);
    return Collector.of(
        multisetSupplier,
        (ms, t) -> ms.add(elementFunction.apply(t), countFunction.applyAsInt(t)),
        (ms1, ms2) -> {
          ms1.addAll(ms2);
          return ms1;
        });
  }
Returns a {@code Collector} that accumulates elements into a multiset created via the specified
{@code Supplier}, whose elements are the result of applying {@code elementFunction} to the
inputs, with counts equal to the result of applying {@code countFunction} to the inputs.
Elements are added in encounter order.

<p>If the mapped elements contain duplicates (according to {@link Object#equals}), the element
will be added more than once, with the count summed over all appearances of the element.

<p>Note that {@code stream.collect(toMultiset(function, e -> 1, supplier))} is equivalent to
{@code stream.map(function).collect(Collectors.toCollection(supplier))}.

@since 22.0