2016-04-13 70 views
2
Function<Map<?,List>,Integer> countMap = (Map)->{ 
    Integer count = 0; 
    for(Object key:Map.keySet()){ 
     count+=Map.get(key).size(); 
    } 
    return count; 
}; 
Integer test = countMap.apply(containedAssets); 

我得到編譯器錯誤:apply(java.util.Map<?,List>> in Function cannot be applied to java.util.Map<java.util.String,List<myClass>>。這種操作是否被Function禁止?我在不使用Map的情況下嘗試了一些不同的代碼,只是使用了一個列表,而Java在使用任何類型的列表方面都沒有問題。將泛型應用於java.util.Function

+0

你想做什麼做什麼呢? – Tunaki

+2

考慮更改爲'Function >,Integer> countMap' –

+2

作爲一個方面說明,僅僅因爲函數返回'Integer',您不必在函數內部使用'Integer'作爲局部變量。你可以使用'int',因爲它足以包裝最終結果而不是裝箱每個中間結果。此外,只要[迭代值](https://docs.oracle.com/javase/8/docs/api/java/util/)時,絕對不要遍歷鍵來爲每個映射調用'Map.get' Map.html#values--) – Holger

回答

6

看起來你想要的是創建一個將返回包含在Map<K, List<V>>所有列表的尺寸的大小之和的函數。

在這種情況下,你可以有

ToIntFunction<Map<?, ? extends List<?>>> function = 
    map -> map.values().stream().mapToInt(List::size).sum(); 

我們可以用ToIntFunction爲返回一個整數的函數,而不是Function<...,Integer>。然後,您的方法的其餘部分可以使用Stream API以更簡單的方式編寫:獲取地圖的值,將每個值映射到由它們的大小組成的IntStream並將元素求和在一起。

+0

它甚至可以是'?擴展集合'而不是列表,因爲'.size()'來自集合 – Ferrybig

5

你已經宣佈你的Function採取Map<?,List>其中類型List是原始的。但是,從您的錯誤消息中,您已通過List<myClass>

與類型參數List<myClass>,即宣告你的Function以下普通的Java命名約定:

Function<Map<?,List<MyClass>>,Integer> countMap = (map)->{ 

因爲只有size()被調用時,Function並不關心什麼類型的參數List是,這樣使它更靈活,你可以用? extends List<?>來代替它,正如評論中提到的那樣。

Function<Map<?, ? extends List<?>>, Integer> countMap = (map)->{ 
+2

或者'?如果類型未知,則擴展列表。 –

+0

因爲只涉及列表大小,所以'List '是可能的。 –

+1

@ Jean-FrançoisSavard你是對的,你的選擇可以更靈活地使用。我會編輯。 – rgettman

4

當你不關心地圖密鑰類型和列表類型,你可以宣佈你的功能如下:

Function<Map<?, ? extends List<?>>, Integer> countMap; 

這意味着:需要地圖,關鍵是任何類型和價值類型是任何類別的擴展名列表任何類型,併產生Integer值。

而且我建議另一種方式來獲得列出的總規模,簡稱爲:

countMap = m -> m.values().stream().mapToInt(List::size).sum();