2017-06-14 31 views
2

我有一個基本上是toMap的收集器函數,但始終是LinkedHashMap,因爲我經常需要這個函數。聲納抱怨這個?通配符泛型在返回類型中。看到這是與toMap方法完全相同的簽名,並且我處於憐憫之中,我將如何用適當的值或泛型替換通配符?如何在自定義Collectors.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); 
} 

這裏是聲納規則的全文:

通用通配符類型應該不圖回報參數一起使用

代碼味道

主要

魷魚:S1452

使用通配符作爲返回類型implicitl y意味着返回值應該被認爲是隻讀的,但是沒有任何辦法來執行這個合約。 讓我們以返回List<? extends Animal>的方法爲例。是否有可能在這份名單上添加一隻狗,一隻貓......我們根本不知道。方法的消費者不應該處理這樣的破壞性問題。

不兼容的代碼示例

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

+0

如果您想知道爲什麼我很費心,這只是3-param版本,我有一個2-param版本,它只是一個keyMapper和valueMapper,它確實減少了代碼。 – Novaterata

+0

聲納問題的全文是什麼? – VGR

+0

@VGR加入全文 – Novaterata

回答

4

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

您可以複製並粘貼該函數(以及它所依賴的函數mapMerger()),並將返回類型聲明爲Collector<T, LinkedHashMap<K,U>, LinkedHashMap<K,U>>。但我認爲保持代碼清潔並與Sonar打交道會更好。也許有一種方法可以表明這是一個誤報,並抑制Sonar的警告。

+0

這就是我的想法,但我需要保證 – Novaterata