I know that this question has been already posted. But after many days searching a solution, i can't find one..
I have two objects, which are converted to HashMap. Once these HashMap I need to merge object 1 into object 2. Namely: These objects can contain null keys.
I want the attribute of object 1 to replace the attribute of object 2 only if the attribute of object 1 is not null.
private <T> Map<String, T> mergeObjects(T first, T second) {
ObjectMapper oMapper = new ObjectMapper();
// On transforme l'objet en une MAP afin de faciliter le merge
Map<String, T> objet1Map = oMapper.convertValue(first, Map.class);
Map<String, T> objet2Map = oMapper.convertValue(second, Map.class);
// Merge object 1 into object 2 (but it merges null values, i don't want that..)
objet2Map.putAll(objet1Map);
return objet2Map;
}
My object is something like that :
{
"environment": "d",
"type": "deploymentconfig",
"component": {
"template": "redis-template.yaml",
"routes": null,
"parameters": {
"REQUESTS_CPU": "25m",
"LIMITS_MEMORY": null,
"PROBE_PATH": null,
"IMAGE_STREAM": "my-image",
"IMAGE_STREAM_TAG": "6.9.6"
}
...
...
}
Edit 1 :
objet1 : {component={template=redis-pvc-component-template.yaml, parameters={REQUESTS_CPU=25m, IMAGE_STREAM=redis-5-rhel7-gtec, IMAGE_STREAM_TAG=5.16_19.12, MEMORY_LIMIT=298Mi}}, type=deploymentconfig}
objet2: {component={parameters={STORAGECLASS=prod}}, environment=p, type=deploymentconfig}
Result ->
{
"environment": "p",
"type": "deploymentconfig",
"component": {
"template": null,
"routes": null,
"parameters": {
"REQUESTS_CPU": null, // disappeared
"LIMITS_MEMORY": null,
"PROBE_PATH": null,
"IMAGE_STREAM": null, // disappeared
"IMAGE_STREAM_TAG": null, // disappeared
"MEMORY_LIMIT": null, // disappeared
"STORAGECLASS": "prod",
"VOLUME": null,
"ROUTE_HOSTNAME": null,
"IMAGE_STREAM_PROJECT": null,
"LIVENESS_PROBE_PATH": null,
"LIVENESS_PROBE_DELAY": null,
"READINESS_PROBE_PATH": null,
"READINESS_PROBE_DELAY": null,
"JAVA_OPTIONS": null,
"ENVIRONMENT": null
}
},
"autoscaler": null
}
As you can see many properties have disappeared after the putAll..
CodePudding user response:
Edit 1:
@Test
public void test() throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(Include.NON_NULL);
HashMap<String,String> map = new HashMap<>();
map.put("some","some");
map.put("other",null);
HashMap<String,Object> othermap = new HashMap<>();
othermap.put("keey","value");
othermap.put("nested",map);
final String asString = objectMapper.writeValueAsString(othermap);
System.out.println(asString);
}
}
without serialization config.
{"keey":"value","nested":{"some":"some","other":null}}
.
with serialization config.
{"keey":"value","nested":{"some":"some"}} //non null inclusion
.
Can you try setting objectmapper to exclude null properties?
mapper.setSerializationInclusion(Include.NON_NULL);
https://www.baeldung.com/jackson-ignore-null-fields#globally
CodePudding user response:
You'll need to merge the individual entries of the maps.
If you just want to keep the value of the first map, you can just use putIfAbsent()
.
Map<String, T> map1 = ...
Map<String, T> map2 = ...
Map<String, T> result = new HashMap<>(map1);
map2.forEach((key, value) -> result.putIfAbsent(key, value);
If you have the value in both maps, you can use merge
to define behavior to calculate what value you want.
map2.forEach((key, value) -> result.merge(key, value, // put if absent
(v1, v2) -> v1); // calculate new value if present in both
}
The latter example I give behaves equivalent to the first, ie it keeps the existing value in the map.