Is there something in Guava that allows me to get the inverse of a Multimap as a (non-multi-) Map?
Consider the following:
static final ImmutableMap<Token, Integer> precedences =
new ImmutableSetMultimap.Builder<Integer, Token>()
.put(0, NOT)
.put(1, ASSIGN)
.put(2, OR)
.put(3, AND)
.putAll(4, NOT_EQUAL, EQUALS)
.putAll(5, LESS_EQUAL, LESS, GREATER_EQUAL, GREATER)
.putAll(6, ADD, SUB)
.putAll(7, MUL, DIV, MOD).build().inverse();
The problem is that the inverse() is a Multimap again, and not a Map. Is there something in Guava that does the conversion for me or do I have to roll my own utility function?
The best I can think of is to use map view of a multimap and Maps.transformValues view (I'm assuming Java 8 here, otherwise use Function instead of method reference):
static final ImmutableMap<Token, Integer> PRECEDENCES = ImmutableMap.copyOf(
Maps.transformValues(TOKENS.inverse().asMap(), Iterables::getOnlyElement));
Using Java 8 streams the above would be:
static final Map<Token, Integer> PRECEDENCES =
TOKENS.inverse().asMap().entrySet().stream()
.collect(Collectors.collectingAndThen(
Collectors.toMap(
Map.Entry::getKey,
e -> Iterables.getOnlyElement(e.getValue())),
ImmutableMap::copyOf));
or if you care about the order:
static final ImmutableMap<Token, Integer> PRECEDENCES =
TOKENS.inverse().asMap().entrySet().stream()
.collect(Collectors.collectingAndThen(
Collectors.toMap(
Map.Entry::getKey,
e -> Iterables.getOnlyElement(e.getValue()),
(u, v) -> {
throw new IllegalStateException(String.format("Duplicate key %s", u));
},
LinkedHashMap::new),
ImmutableMap::copyOf));
or hopefully in Guava 21:
static final Map<Token, Integer> PRECEDENCES =
TOKENS.inverse().asMap().entrySet().stream()
.collect(ImmutableMap.toImmutableMap(
Map.Entry::getKey,
e -> Iterables.getOnlyElement(e.getValue())));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With