java - 如何在函数式接口和方法引用上下文中的函数之间解释参数和参数
问题描述
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 类型的引用作为参数的函数匹配。
解决方案
请注意,这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
作为参数被“提升”!这并不是真正想要发生的事情,但这仍然可以解释为什么这首先是可能的。
推荐阅读
- java - 垂直和对角循环遍历矩阵
- php - codeigniter form_hidden 不发布数据
- java - 如何使用 nio 将阅读器写入文件?
- c# - 如何在列表c#中查找包含n个或更多顺序重复项的组
- openssl - 我想在 Contiki OS 的 Cooja 模拟器中使用 OpenSSL,但我无法集成它
- amazon-web-services - AWS Auto Scaling Fargate 任务根据 SQS 队列长度向上或向下
- swift - cvPixelBuffer 到 CGImage 的转换只给出黑白图像
- excel - Excel VBA / 导入默认大小的 WMF 图像会产生巨大的图像
- java - 如何从给定的 IPAddress 打印所有子网?
- excel - 连续平均每个其他单元格