Created
December 10, 2016 21:47
-
-
Save MarkyMarkMcDonald/2d9db48c444cff409494738f12a36073 to your computer and use it in GitHub Desktop.
flattenedToReversedMutliImmutableMap collector for guava
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@danfinnie