Search code examples
javajava-8guavacollectors

Java 8 Collector for Guava's ImmutableListMultimap<String,T>


Looking for an easy way to collect collection of KeyAndValues having fields - String and List<T> to ImmutableListMultimap<String,T>? Tried to do something like,

 Collector.of(
          ImmutableListMultimap.Builder::new,
          ImmutableListMultimap.Builder<String,List<T>>::putAll,
          (b1, b2) -> b1.putAll(b2.build()),
          (builder) -> builder.build());

putAll takes Key, List<T>. I am not sure how to achieve this in combiner.

EDIT :

 @Value(staticConstructor = "of")
 private static class KeyAndValues<T> {

    private final String key;
    private final List<T> values;
}

Solution

  • Not sure about the methods available on KeyAndValues<T>, but how about this?

      public static <T> Collector<KeyAndValues<T>,
                                  ImmutableListMultimap.Builder<String, T>, 
                                  ImmutableListMultimap<String, T>> toImmutableMultimap()
      {
        return Collector.of(
            ImmutableListMultimap.Builder::new,
            (b, kav) -> b.putAll(kav.getKey(), kav.getValues()),
            (builder1, builder2) -> builder1.putAll(builder2.build()),
            (builder) -> builder.build());
      }
    

    Alternatively, if you would prefer to hide the accumulator details, you can use something like this:

    public static <T> Collector<KeyAndValues<T>,
                                ?,
                                ImmutableListMultimap<String, T>> toImmutableMultimap()
    {
      return Collector.of(
        ImmutableListMultimap.Builder<String, T>::new,
        (b, kav) -> b.putAll(kav.getKey(), kav.getValues()),
        (builder1, builder2) -> builder1.putAll(builder2.build()),
        (builder) -> builder.build());
    }