首页 > 解决方案 > 如何在函数式接口和方法引用上下文中的函数之间解释参数和参数

问题描述

interface MyFunc<T> {
  boolean func(T v1, T v2);
}

class Foo {
  private int value;

  Foo(int v) { value = v; }

  boolean isGreater(Foo obj) {   <-- (*)
    return value > obj.value;    <-- (**)    
  }
}

class Demo {
  static <T> int counter(T[] vals, MyFunc<T> f, T v) {
    int count = 0;

    for (int i = 0; i < vals.length; i++)
      if (f.func(vals[i], v)) 
        count++;

    return count;
  }

  public static void main (String [] args) {
    int count;

    Foo[] values = new Foo[10];

    for (int i = 0; i < values.length; i++)
      values[i] = new Foo(i);

    count = counter(values, Foo::isGreater, new Foo(5));

    System.out.println("values bigger " + count);
  }
}

此代码有一个函数 isGreater (*),它计算小于作为参数传递的值的值的数量。我的困惑是如何interface MyFunc<T>推断比较两个 Foo 实例变量值的返回语句(**)有 2 个参数。为了更清楚地说明如何MyFunc<T>(T v1, T v2)其作为参数,这是与将isGreater(Foo obj)Foo 类型的引用作为参数的函数匹配。

标签: java

解决方案


请注意,这isGreater是一个实例方法。您将如何调用 的实例方法Foo?除了方法所需的所有参数之外,您还需要 的实例。Foo

在 的情况下isGreater,您实际上需要两个实例Foo来调用它(即使它只需要 1Foo作为参数):

foo1.isGreater(foo2)
^^^^           ^^^^

另请注意,当您使用时Foo::isGreater,您没有给它任何Foo调用实例isGreater!通常这不适用于实例方法,但 Java 语言设计者看到了它的出现并允许这样做。

在任何情况下,您都需要一个Foo要调用的isGreater实例和另一个要作为参数传递的实例。因此,我们可以像这样“重写”isGreater为静态方法:

public static boolean isGreater(Foo foo1, Foo foo2) {
    return foo1.isGreater(foo2);
}

您调用的实例isGreater作为参数被“提升”!这并不是真正想要发生的事情,但这仍然可以解释为什么这首先是可能的。


推荐阅读