Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending an ImmutableMap with additional or new values

Tags:

java

guava

Much like how an ImmutableList could be extended as such:

ImmutableList<Long> originalList = ImmutableList.of(1, 2, 3);
ImmutableList<Long> extendedList = Iterables.concat(originalList, ImmutableList.of(4, 5));

If I have an existing map, how could I extend it (or create a new copy with replaced values)?

ImmutableMap<String, Long> oldPrices = ImmutableMap.of("banana", 4, "apple", 7);
ImmutableMap<String, Long> newPrices = … // Increase apple prices, leave others.
                                         //  => { "banana": 4, "apple": 9 }

(Let's not seek an efficient solution, as apparently that doesn't exist by design. This question rather seeks the most idiomatic solution.)

like image 442
Andres Jaan Tack Avatar asked Apr 23 '15 16:04

Andres Jaan Tack


People also ask

How do you make a map immutable?

We used to use the unmodifiableMap() method of Collections class to create unmodifiable(immutable) Map. Map<String,String> map = new HashMap<String, String>(); Map<String,String> immutableMap = Collections. unmodifiableMap(map); Lets test this in JShell.

Is map mutable in Java?

Mutable maps supports modification operations such as add, remove, and clear on it. Unmodifiable Maps are “read-only” wrappers over other maps. They do not support add, remove, and clear operations, but we can modify their underlying map.


1 Answers

You could explicitly create a builder:

ImmutableMap<String, Long> oldPrices = ImmutableMap.of("banana", 4, "apple", 7);
ImmutableMap<String, Long> newPrices =
    new ImmutableMap.Builder()
    .putAll(oldPrices)
    .put("orange", 9)
    .build();

EDIT:
As noted in the comments, this won't allow overriding existing values. This can be done by going through an initializer block of a different Map (e.g., a HashMap). It's anything but elegant, but it should work:

ImmutableMap<String, Long> oldPrices = ImmutableMap.of("banana", 4, "apple", 7);
ImmutableMap<String, Long> newPrices =
    new ImmutableMap.Builder()
    .putAll(new HashMap<>() {{
        putAll(oldPrices);
        put("orange", 9); // new value
        put("apple", 12); // override an old value
     }})
    .build();
like image 128
Mureinik Avatar answered Oct 24 '22 04:10

Mureinik