Skip to content

Instantly share code, notes, and snippets.

@jwgmeligmeyling
Last active September 27, 2020 10:16
Show Gist options
  • Save jwgmeligmeyling/051fcb5d76ad01eb652f to your computer and use it in GitHub Desktop.
Save jwgmeligmeyling/051fcb5d76ad01eb652f to your computer and use it in GitHub Desktop.
Collectors for Guava Multimaps

Collectors for Guava Multimaps

Collectors for the Guava Multimaps. I had to copy the abstract CollectorImpl code from the java.util.stream package, but managed to get it relatively compact using Project Lombok code generation.

package nl.tudelft.ewi.gitolite.config.util;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.TreeMultimap;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Value;
import lombok.experimental.Accessors;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
/**
* @author Jan-Willem Gmelig Meyling
*/
@Value
@Accessors(fluent = true)
@AllArgsConstructor(access = AccessLevel.PACKAGE)
public class MultimapCollector<T, A> implements Collector<T, A, A> {
static final Set<Collector.Characteristics> CH_ID
= Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH));
private final Supplier<A> supplier;
private final BiConsumer<A, T> accumulator;
private final BinaryOperator<A> combiner;
private final Function<A, A> finisher;
private final Set<Characteristics> characteristics = CH_ID;
MultimapCollector(Supplier<A> supplier,
BiConsumer<A, T> accumulator,
BinaryOperator<A> combiner) {
this(supplier, accumulator, combiner, Function.identity());
}
public static <T, K, U, M extends Multimap<K, U>>
MultimapCollector<T, M> toMultiMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
Supplier<M> mapSupplier) {
BiConsumer<M, T> accumulator = (map, element) -> map.put(keyMapper.apply(element), valueMapper.apply(element));
return new MultimapCollector<>(mapSupplier, accumulator,
(kvMultimap, kvMultimap2) -> {
kvMultimap.putAll(kvMultimap2);
return kvMultimap;
});
}
public static <T, K, U>
MultimapCollector<T, HashMultimap<K, U>> toHashMultiMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
return toMultiMap(keyMapper, valueMapper, HashMultimap::create);
}
public static <T, K, U>
MultimapCollector<T, LinkedHashMultimap<K, U>> toLinkedHashMultiMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
return toMultiMap(keyMapper, valueMapper, LinkedHashMultimap::create);
}
public static <T, K, U>
MultimapCollector<T, ArrayListMultimap<K, U>> toArrayListMultimap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
return toMultiMap(keyMapper, valueMapper, ArrayListMultimap::create);
}
public static <T, K extends Comparable<K>, U extends Comparable<U>>
MultimapCollector<T, TreeMultimap<K, U>> toTreeMultiMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
return toMultiMap(keyMapper, valueMapper, TreeMultimap::create);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment