Created
January 20, 2016 21:04
-
-
Save jarrodhroberson/780d38e41df96f2be980 to your computer and use it in GitHub Desktop.
Overlay/Merge an ImmutableMap over another ImmutableMap
This file contains hidden or 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
import java.util.Map; | |
import javax.annotation.Nonnull; | |
import javax.annotation.Nullable; | |
import com.google.common.collect.ImmutableMap; | |
import com.google.common.collect.Maps; | |
public class MapTransforms | |
{ | |
/** | |
* This assumes that <code>defaults</code> specifies the complete domain of the set of keys/values supported by <code>overlay</code>. | |
* <p/> | |
* This is implemented as a <code>View</code> as described in the documentation for {@link com.google.common.collect.Maps#transformEntries(Map, Maps.EntryTransformer)} and does not copy either map and returns the values on demand. | |
* This means if you want to transform the entire <code>Map</code> to the merged version at once you need to wrap the return value in <code>ImmutableMap.copyOf()</code> which will eagerly | |
* apply the transformation and process the entire map only once. | |
* <p/> | |
* There is no sanity check on this that a given key exists in the <code>defaults.keySet()</code> | |
* | |
* @see com.google.common.collect.Maps.EntryTransformer | |
* @param defaults complete domain to overlay new <code>Map</code> onto | |
* @param overlay <code>Map</code> contents to replace what is contained in <code>defaults</code> | |
* @param <K> Key type | |
* @param <V> Value type | |
* @return returns a <code>View</code> as an <code>ImmutableMap</code> that returns the values in <code>overlay</code> if they exist otherwise the value in <code>defaults</code>. | |
*/ | |
public static <K, V> Map<K, V> overlay(@Nonnull final Map<K, V> defaults, @Nonnull final Map<K, V> overlay) | |
{ | |
return Maps.transformEntries(defaults, new Maps.EntryTransformer<K, V, V>() | |
{ | |
@Override | |
public V transformEntry(@Nullable final K key, @Nullable final V value) | |
{ | |
return overlay.containsKey(key) ? overlay.get(key) : value; | |
} | |
}); | |
} | |
/** | |
* This does the same thing that {@link #overlay(Map, Map)} does, but wraps the return value in {@link ImmutableMap#copyOf(Map)} to eagerly apply the transform. | |
* | |
* @param defaults complete domain to overlay new <code>Map</code> onto | |
* @param overlay <code>Map</code> contents to replace what is contained in <code>defaults</code> | |
* @param <K> Key type | |
* @param <V> Value type | |
* @return applyes {@link #overlay(Map, Map)} and wraps the result in {@link ImmutableMap#copyOf(Map)} | |
*/ | |
public static <K,V> Map<K,V> merge(@Nonnull final Map<K,V> defaults, @Nonnull final Map<K,V> overlay) | |
{ | |
return ImmutableMap.copyOf(overlay(defaults,overlay)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment