I have the following code on which sonar is throwing a check "Optional#isPresent()" before accessing value error.
private Map<String, Map<String, Object>> generateMap(Object object) {
return Optional.ofNullable((List<Map<String, Object>>) object).map((obj) -> functionListToMap.apply(obj)).get();
}
I've tried the following the way to fix the error, but I'm not sure if this is the best coding standard.
private Map<String, Map<String, Object>> generateMap(Object object) {
Optional<List<Map<String, Object>>> result = Optional.ofNullable((List<Map<String, Object>>) object);
if(result.isPresent()) {
return result.map((obj) -> functionListToMap.apply(obj)).get();
}
else {
return null;
}
}
Can someone please suggest is there is any other best way to do this?
The unchecked cast is something you should try to avoid. If you know that your method can only handle List<Map<String, Object>>, then your parameter should be typed as such.
I'm assuming functionListToMap is a Function<>. Calling it like that (functionListToMap.apply()) almost defeats the purpose of a functional interface. Instead, just use it as a lambda.
In this case, where you just want to return null if there is no data, you can use orElse():
private Map<String, Map<String, Object>> generateMap(List<Map<String, Object>> list) {
return Optional.ofNullable(list).map(functionListToMap).orElse(null);
}
In the case you want to return an empty Map if no data is present, use orElseGet() instead:
private Map<String, Map<String, Object>> generateMap(List<Map<String, Object>> list) {
return Optional.ofNullable(list).map(functionListToMap).orElseGet(HashMap::new);
}
The difference from using orElse(new HashMap<>()) is that in the case of orElse, the other object is instantiated every time, regardless of whether it is used or not, while with orElseGet() the Supplier (HashMap::new) is only called if needed.
You could also rewrite the method without Optional:
private Map<String, Map<String, Object>> generateMap(List<Map<String, Object>> list) {
if (list == null) {
return null;
} else {
return functionListToMap.apply(list);
}
}
Or again, but also rewrite functionListToMap to be a method:
private Map<String, Map<String, Object>> generateMap(List<Map<String, Object>> list) {
if (list == null) {
return null;
} else {
return functionListToMap(list);
}
}