java - 使用双冒号运算符在Java中引用任意对象的实例方法
问题描述
class Point {
int x;
int y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
public String toString() {
return "Point(" + x + ", " + y + ")";
}
boolean filter() {
return this.x == this.y;
}
}
public class Test {
public static void main(String[] args) {
List<Point> list = new ArrayList<>();
list.add(new Point(0, 0));
list.add(new Point(1, 2));
list.add(new Point(-1, -1));
Supplier<Boolean> s = Point::filter; // Compilation Error (line n1)
list.stream().filter(Point::filter).forEach(System.out::println); //No Error (line n2)
}
}
在第 n2 行,如果我使用类名访问实例方法,则隐式创建一个访问的任意对象,但在第 n1 行,我得到编译错误。在哪些场景下会创建任意隐式对象?
如果我使用对象,我不会收到错误
new Point(0,0)::filter
解决方案
在哪些场景下会创建任意隐式对象?
在这两种情况下,都不会创建新对象。
Supplier<Boolean> s = Point::filter;
不能编译,因为 aSupplier<Boolean>
代表一个函数,它可以在你Boolean
不给它任何输入的情况下给你 a ,即我应该能够做到:
Boolean b = s.get(); // note that I am not giving "get" any input
// but s refers to the filter method in Point, which is an instance method
// I don't have any Point object in my code, yet somehow I still got a Boolean,
// so clearly this doesn't make sense
如您所见,Point::filter
不是这样的功能。要调用它,我需要先给它一个Point
对象,然后它会给我一个boolean
. Predicate<Point>
是一个可以表示这种功能的函数式接口,所以我可以这样做:
Predicate<Point> pred = Point::filter;
boolean b = pred.test(new Point(0, 0)); // here I am giving red the instance of Point on which filter should be called
请注意,您没有filter
在方法引用 ( ) 中指定应该调用哪个对象Point::filter
,而是由调用者 ( pred.test(...)
) 指定。这就是为什么Point::filter
称为“对任意对象的实例方法的引用”。
最后,Stream.filter
可以接受您的Point::filter
方法的原因是因为它实际上需要 aPredicate<Point>
,而不是 aSupplier<Boolean>
作为参数!
当您调用时forEach
,Point::filter
会在每个流元素上调用。具体如何做到这一点取决于流管道的实现细节。
推荐阅读
- dart - 从对象列表中调用对象元素
- protocol-buffers - 恢复原始定义中的保留字段可以吗?
- mysql - 带有指标的 MySQL 查询审计日志
- node.js - 通过 ObjectId 发布到 db 中的嵌套数组
- sql - Big Query - 数据去识别 PII
- android - 应用程序在 PlayStore 中发布后谷歌地图空白显示
- lua - 全局“等待”不可调用(零值)
- reactjs - Material UI 5:由样式化实用程序定义的类在嵌套元素中不起作用
- c# - Dispatcher.BeginInvoke(new...ProgressBarProcess.Value = 1 没有显示?
- java - 我们正在使用 Java7,我正在尝试使用 yaml 生成 ApiClient 但存在编译问题