Seems that ValueMaps are immutable, even if you use .put() you will get run time errors.
Instead I change everywhere which used ValueMap to use HashMap<String,Object> instead, and copy each ValueMap into this. Then I can use the full power of maps.
public void copyProps(ValueMap from, HashMap<String,Object> to) {
// ignore jrc: and sling: object properties.
from.forEach((key, value) -> {
if (!key.startsWith("jcr:") && !key.startsWith("sling:")) {
to.put(key, value);
}
});
}
I use the above code to convert ValueMaps into HashMaps, and to also combine several page components VAlueMaps into a single HashMap so I can send the page back as json (using Gson on the resultant master hashmap).
This relies on not using the same field names on each components properties.