Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save MarkyMarkMcDonald/2d9db48c444cff409494738f12a36073 to your computer and use it in GitHub Desktop.
Save MarkyMarkMcDonald/2d9db48c444cff409494738f12a36073 to your computer and use it in GitHub Desktop.
flattenedToReversedMutliImmutableMap collector for guava
package com.example;
import com.google.common.collect.*;
import org.junit.Test;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Stream;
import static com.google.common.collect.ImmutableList.of;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
public class CollectorsTest {
public class Car {
private String id;
private Integer modelYear;
private String color;
private String brand;
private RoofType roofType;
private List<Integer> passengerAges;
public Car(String color, List<Integer> passengerAges) {
this.color = color;
this.passengerAges = passengerAges;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Integer getModelYear() {
return modelYear;
}
public void setModelYear(Integer modelYear) {
this.modelYear = modelYear;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public RoofType getRoofType() {
return roofType;
}
public void setRoofType(RoofType roofType) {
this.roofType = roofType;
}
public List<Integer> getPassengerAges() {
return passengerAges;
}
}
@Test
public void multiMapFlattenThenReverse() throws Exception {
Car familyCar = new Car("red", of(5, 18, 65));
Car clownCar = new Car("blue", of(33, 34, 5));
ImmutableList<Car> cars = of(clownCar, familyCar);
// [
// {red, [5, 18, 65]},
// {blue, [33, 34, 5]}
// ]
// ?????
// {
// 5 => ["red", "blue"],
// 18 => ["red"],
// 65 => ["red"],
// 33 => ["blue"],
// 34 => ["blue"],
// }
//
ImmutableSetMultimap<Integer, String> stuff = cars
.stream()
.collect(flattenedToReversedMultiImmutableMap(Car::getColor, Car::getPassengerAges));
assertThat(stuff.get(5), equalTo(ImmutableSet.of("red", "blue")));
assertThat(stuff.get(18), equalTo(ImmutableSet.of("red")));
assertThat(stuff.get(33), equalTo(ImmutableSet.of("blue")));
stuff = cars
.stream()
.collect(flattenedToReversedMultiImmutableMap(Car::getColor, (Car car) -> car.getPassengerAges().stream()));
assertThat(stuff.get(5), equalTo(ImmutableSet.of("red", "blue")));
assertThat(stuff.get(18), equalTo(ImmutableSet.of("red")));
assertThat(stuff.get(33), equalTo(ImmutableSet.of("blue")));
}
public interface NonConflictingFunction<T, K> extends Function<T, K> { }
public <T, K, V> Collector<T, ImmutableSetMultimap.Builder<K, V>, ImmutableSetMultimap<K, V>> flattenedToReversedMultiImmutableMap(Function<T, V> mapValues, NonConflictingFunction<T, Collection<K>> mapKeys) {
return flattenedToReversedMultiImmutableMap(mapValues, mapKeys.andThen(Collection::stream));
}
public <T, K, V> Collector<T, ImmutableSetMultimap.Builder<K, V>, ImmutableSetMultimap<K, V>> flattenedToReversedMultiImmutableMap(Function<T, V> mapValues, Function<T, Stream<K>> mapKeys) {
return Collector.of(
ImmutableSetMultimap.Builder::new,
(builder, car) -> mapKeys.apply(car).forEach(age -> builder.put(age, mapValues.apply(car))),
(builder1, builder2) -> builder1.putAll(builder2.build()),
ImmutableSetMultimap.Builder::build);
}
}
@MarkyMarkMcDonald
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment