I have a Collector function that is basically toMap but always a LinkedHashMap as I need this often. Sonar complains about the ? wildcard generic in the return type. Seeing as this is the exact same signature as the toMap method, and I'm at it's mercy, how would I replace the wildcard with a proper value or generic?
I've tried Map<K,U>
and adding an M extends Map<K,U>
and LinkedHashMap versions of those as well, but nothing compiles.
Any suggestions?
Or is this impossible as I am using Collectors.toMap which uses a wildcard?
public static <T, K, U> Collector<T, ?, LinkedHashMap<K, U>> toLinkedHashMap(
Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> merger) {
return Collectors.toMap(keyMapper, valueMapper, merger, LinkedHashMap::new);
}
Here is the full text of the Sonar rule:
Generic wildcard types should not be used in return parameters
Using a wildcard as a return type implicitly means that the return value should be considered read-only, but without any way to enforce this contract.
Let's take the example of method returning a List<? extends Animal>
. Is it possible on this list to add a Dog, a Cat, ... we simply don't know. The consumer of a method should not have to deal with such disruptive questions.
List<? extends Animal> getAnimals(){...}
It is impossible as long as you use Collections.toMap()
.
You could copy-and-paste that function (and the mapMerger()
function on which it depends), declaring the return type as Collector<T, LinkedHashMap<K,U>, LinkedHashMap<K,U>>
. But I think it would be better to keep your code clean and deal with Sonar. Perhaps there's a way to indicate that this is a false positive, and suppress warnings from Sonar.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With