2015-08-23 30 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