guava/src/com/google/common/collect/ImmutableMultiset.java
public static <T, E> Collector<T, ?, ImmutableMultiset<E>> toImmutableMultiset(
      Function<? super T, ? extends E> elementFunction, ToIntFunction<? super T> countFunction) {
    checkNotNull(elementFunction);
    checkNotNull(countFunction);
    return Collector.of(
        LinkedHashMultiset::create,
        (multiset, t) ->
            multiset.add(checkNotNull(elementFunction.apply(t)), countFunction.applyAsInt(t)),
        (multiset1, multiset2) -> {
          multiset1.addAll(multiset2);
          return multiset1;
        },
        (Multiset<E> multiset) -> copyFromEntries(multiset.entrySet()));
  }
public static <T, E> Collector<T, ?, ImmutableMultiset<E>> toImmutableMultiset(
      Function<? super T, ? extends E> elementFunction, ToIntFunction<? super T> countFunction) {
    checkNotNull(elementFunction);
    checkNotNull(countFunction);
    return Collector.of(
        LinkedHashMultiset::create,
        (multiset, t) ->
            multiset.add(checkNotNull(elementFunction.apply(t)), countFunction.applyAsInt(t)),
        (multiset1, multiset2) -> {
          multiset1.addAll(multiset2);
          return multiset1;
        },
        (Multiset<E> multiset) -> copyFromEntries(multiset.entrySet()));
  }
Returns a {@code Collector} that accumulates elements into an {@code ImmutableMultiset} 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.

<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 22.0