自定义 Collectors.toMap 时如何替换通配符泛型

How to replace wildcard generic when customizing Collectors.toMap

我有一个 Collector 函数,它基本上是 toMap,但总是一个 LinkedHashMap,因为我经常需要它。声纳抱怨? return 类型中的通配符泛型。鉴于这是与 toMap 方法完全相同的签名,我听天由命,我该如何用适当的值或泛型替换通配符?

我已经尝试 Map<K,U> 并添加了 M extends Map<K,U> 和 LinkedHashMap 版本,但没有编译。

有什么建议吗?

或者这是不可能的,因为我正在使用使用通配符的 Collectors.toMap?

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);
}

这里是 Sonar 规则的全文:

不应在 return 参数中使用通用通配符类型

代码味道

主要

鱿鱼:S1452

将通配符用作 return 类型隐式意味着 return 值应被视为只读,但没有任何方式来执行此合同。 让我们以方法 returning a List<? extends Animal> 为例。是否有可能在此列表中添加一只狗、一只猫……我们根本不知道。方法的使用者不必处理此类破坏性问题。

不合规的代码示例

List<? extends Animal> getAnimals(){...}

不可能的,只要你用Collections.toMap()

您可以复制并粘贴该函数(以及它所依赖的 mapMerger() 函数),将 return 类型声明为 Collector<T, LinkedHashMap<K,U>, LinkedHashMap<K,U>>。但我认为保持代码清洁并处理 Sonar 会更好。也许有一种方法可以表明这是误报,并禁止来自 Sonar 的警告。