I have an Iterable<Map<? extends K, ? extends V>>
and I'd like to provide a view into the union of these maps' entry sets, i.e. Set<Map.Entry<K, V>>
.
I can construct a new Set
like so (the cast triggers an unchecked warning, but compiles):
ImmutableSet.Builder<Map.Entry<K, V>> builder = ImmutableSet.builder();
for(Map<? extends K, ? extends V> map : chain) {
for(Map.Entry<? extends K, ? extends V> e : map.entrySet()) {
builder.add((Map.Entry<K, V>) e);
}
}
return builder.build();
However this requires copying the sets, and doesn't stay in-sync with the backing maps. I've tried things like:
Set<Map.Entry<K, V>> unionSet = ImmutableSet.of();
for(Map<? extends K, ? extends V> map : chain) {
unionSet = Sets.union((Set<Map.Entry<K, V>>)map.entrySet(), unionSet);
}
return unionSet;
But this fails to compile, with the error:
Cannot cast from Set<Map.Entry<capture#27-of ? extends K, capture#28-of ? extends V>> to Set<Map.Entry<K,V>>
I expected a similar unsafe cast, but that seems forbidden in this context, presumably due to the nested generics.
So two questions:
- Why is this sort of cast forbidden, yet casts of the top-level generic is allowed?
- Is there a better way to provide a view into the union of these sets (with the type
Set<Map.Entry<K, V>>
)?