Java 8方法参考

时间:2017-03-26 01:18:30

标签: java

作为任意方法参考的一部分:

为什么允许这样做?

/Users/MacAdmin/Documents/spark-2.1.0-bin-hadoop2.7/bin/spark-submit --jars spark-streaming-kafka-assembly_2.10-1.6.3.jar spark_streaming_sample.py

为什么不允许这样做?

Predicate<String> p1 = String::isEmpty;

2 个答案:

答案 0 :(得分:1)

在您的第一个示例中,您创建了一个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>,但您缺少String方法所需的put参数。不幸的是,没有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

答案 1 :(得分:1)

基本问题是put()不是类型的方法 - 类型具有方法范围且可以推断的方法,它是一种通用实例方法 - 从中​​获取类型的方法实例的类型。

此外,您与方法引用的类型及其通用参数不匹配。我假设你的意思是BiFunction,而不是BiConsumer

让我们看一下做什么的工作:

HashMap<String, Integer> instance = new HashMap<>();
BiFunction<String, Integer, Integer> b1 = instance::put;

如果你的意思是BiConsumer,那么这也适用:

BiConsumer<String, Integer> b1 = instance::put;

正如我所说,因为该方法从实例中获取其类型,所以您需要一个类型化的实例。