作为任意方法引用的一部分:
为什么这是允许的?
Predicate<String> p1 = String::isEmpty;为什么不允许这样做?
BiConsumer<HashMap<String,Integer>, Integer> b1 = HashMap<String,Integer>::put;发布于 2017-03-26 01:36:51
在第一个示例中,您正在创建一个Predicate,它以一个String作为输入。这与不带任何参数的String.isEmpty()匹配。谓词仅对字符串实例进行操作。
至于第二个例子,让我们检查一下put方法:
public V put(K key, V value)由于您使用的是HashMap<String, Integer>,这将是
public Integer put(String key, Integer value)如您所见,该方法本身需要两个参数。由于您希望将其作为方法引用传递,因此除了这两个参数之外,它还需要HashMap<String, Integer>。
BiConsumer<HashMap<String, Integer>, Integer> b1 = HashMap<String, Integer>::put;在这里,您正确地将第一个泛型类型参数标记为HashMap<String, Integer>,但是您缺少了put方法需要的String参数。不幸的是,没有TriConsumer,但是您可以很容易地为它定义自己的接口:
@FunctionalInterface
public interface TriConsumer<T, U, V> {
void accept(T t, U u, V v);
}不需要@FunctionalInterface注释,但它向读者传达了这个接口可用作lambda表达式或方法引用的赋值目标的意图。
现在您可以将引用分配给put
TriConsumer<HashMap<String, Integer>, String, Integer> consumer = HashMap<String, Integer>::put;
HashMap<String, Integer> map = new HashMap<>();
consumer.accept(map, "Key", 123);
System.out.println(map.get("Key")); // prints 123发布于 2017-03-26 01:40:51
基本问题是,put()不是一个类型化方法--一个类型具有方法范围并可以推断的方法,它是一个泛型实例方法--一个从实例类型获取其类型的方法。
此外,您还与方法引用的类型及其泛型参数不匹配。我以为你指的是BiFunction而不是BiConsumer。
让我们来看看什么起作用了:
HashMap<String, Integer> instance = new HashMap<>();
BiFunction<String, Integer, Integer> b1 = instance::put;如果您真的是指BiConsumer,这也适用于:
BiConsumer<String, Integer> b1 = instance::put;正如我已经说过的,因为该方法从实例中获取其类型,所以您需要一个类型化实例。
https://stackoverflow.com/questions/43023900
复制相似问题