2015-08-23 71 views
6

在java中,您可以將Type參數添加到靜態方法中,以創建處理泛型的方法。你可以用lambdas做同樣的事嗎?在Java中創建通用lambdas

在我的代碼有

final private static <K,V> Supplier<Map<K, List<V>> supplier=HashMap::new; 

我試圖做的類型參數,如它的功能,但它不會讓我。

如果我做的:

final private static Supplier<Map<?, List<?>>> supplier=HashMap::new; 

它不接受,我嘗試使用它的論點。我能做什麼?此

+1

這不可能是一個變量。事實上,聲明一個像'WhateverClassThatSupportsGenerics var = ...;'這樣的變量是無用的,除非它是一個方法的參數。 –

+0

你在哪裏嘗試使用第二個聲明? (第一個,正如你可能發現的,在合成上是無效的。) – Makoto

+1

不可能構造一個有界的通用對象。你的代碼行失敗的原因同樣是'新的HashMap >'是合法的,但'新的HashMap >'不是。 '''意思是「我不知道這個HashMap使用了什麼類型」,但是當你創建一個HashMap時,你總是知道你打算如何放置它(即使你決定使用java.lang.Object)。 – VGR

回答

8

一種解決方法可以是將參考方法包裝到一個方法,使目標類型扣在調用位置解析類型:

import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
import java.util.function.Supplier; 

public class GenericLambda 
{ 
    // Syntactically invalid 
    //final private static <K,V> Supplier<Map<K, List<V>> supplier=HashMap::new; 

    final private static Supplier<Map<?, List<?>>> supplier=HashMap::new; 

    // A workaround 
    private static <K,V> Supplier<Map<K, List<V>>> supplier() 
    { 
     return HashMap::new; 
    } 


    public static void main(String[] args) 
    { 
     // Does not work 
     //useSupplier(supplier); 

     // Works 
     useSupplier(supplier()); 
    } 

    private static <K, V> void useSupplier(Supplier<Map<K, List<V>>> s) 
    { 
     System.out.println(s.get()); 
    } 
} 
+0

我認爲你需要在'Map '(或'Map ''HashMap :: new' ')但不是'Map >')。看看'Collections.emptyList()'是如何實現的。 – NoDataFound

+1

@NoDataFound不知道你的意思,但是在這裏,不需要強制轉換(雖然在這種情況下殘酷的強制轉換也可能是安全的,因爲所有類型參數在編譯時會變成「Object」...) – Marco13

+0

@ NoDataFound:'Collections.emptyList()'返回的列表是不可變的,因此可以總是返回相同的對象並且只是施放它。然而,在這種情況下,你總是得到一個新的'HashMap',並且使用'HashMap :: new',編譯器可以自動推斷出正確的通用參數。儘管如此,總是可以拋出並返回靜態字段。但在這種情況下鑄造有點不方便:您需要使用'(供應商<地圖 >>)(供應商)供應商'。它會產生關於未經檢查的演員的警告,演出通常不會產生任何影響。 – siegi