如何在不调用call方法的情况下调用functor对象的函数

时间:2017-04-07 15:21:29

标签: java lambda functional-programming functor

我有一个仿函数对象:

private static Func1<MyEvent, Observable<Data>> getDataOnEvent = new Func1<MyEvent, Observable<Data>>() {
    @Override
    public Observable<Data> call(MyEvent event) {
        return ApiFactory.get().getData()
    }
};

对于它的调用,我需要这样做:

result = getDataOnEvent.call(someEvent)

是否可以这样做:

result = getDataOnEvent(someEvent)

就像使用Python和Javascript一样?也许是新版本的java或者像Lombok这样的库?

2 个答案:

答案 0 :(得分:1)

只需使用,

private static Observable<Data> getDataOnEvent(MyEvent event) {
    return ApiFactory.get().getData()
}

您可以在需要时致电result = getDataOnEvent(someEvent);。正如您所看到的,以这种方式编写,将比调用端的五个字母.call节省更多的锅炉代码。

如果Func1是功能界面,则可以在ContainingClass::getDataOnEvent所需的任何地方使用Func1<MyEvent, Observable<Data>>。如果您更喜欢使用简单标识符static作为函数,也可以将其存储到getDataOnEvent变量中:

private static Func1<MyEvent, Observable<Data>> getDataOnEvent
                                              = ContainingClass::getDataOnEvent;

然后,您可以使用getDataOnEvent(event)来调用它,或getDataOnEvent在需要时将其称为Func1实例。

如果Func1不是功能界面,那么你不能以这种紧凑的形式创建函数,但另一方面,在这种情况下,要求支持调用是不合理的一种任意方法,无需明确命名。

答案 1 :(得分:1)

我知道你的意思,groovy代码call a closure是这样的:

def code = { 123 };

//can be called like any other method if the variable is a closure.
assert code() == 123;
//can be call explicitly by using `call` method
assert code.call() == 123;

javascript代码call a function是这样的:

let code = () => 123;

//can be called like any other function if the variable is a function.
assert code() == 123;
//can be call explicitly by using `call` method
assert code.call() == 123;

但是我可以告诉你java gammar不支持字段/变量的这个功能,也许在下一个jdk中将启用这个字段/变量引用Callable的功能。

幸运的是,如果静态成员是一种方法,Single-Static-Import Declarations支持直接调用方法,例如:

import static java.lang.Math.abs;

assert abs(-1) == 1;

如果你真的想制作一个名为方法调用的标识符,你可以伪造这样的东西:

class ApiFactory {

    public static Func1<MyEvent, Observable<Data>> getDataOnEvent = new Func1<MyEvent, Observable<Data>>() {
        public Observable<Data> call(MyEvent event) {
            return ApiFactory.get().getData();
        }
    };

    public static Observable<Data> getDataOnEvent(MyEvent event) {
        return getDataOnEvent.call(event);
    }

}

然后你可以这样打电话:

import static ${package}.ApiFactory.getDataOnEvent;
// which is calling a static method
result = getDataOnEvent(event);
// which is calling a static field
result = getDataOnEvent.call(event);