假设一个C ++中的仿函数的简单例子:
class Test2 {
private:
double a;
public:
Test2 (double a_) : a(a_){}
double operator () () {return 10*a;}
};
template <typename Function>
double test ( Function function ) {return function();}
int main(int argc, char* argv[]) {
double a = test( Test2(5) );
return 0;
}
有没有办法在Java中实现这种结构(例如使用接口Functor)?你能给我一个简短的例子吗?谢谢你的帮助。
答案 0 :(得分:2)
在Java 8中,您可以使用DoubleSupplier
接口从对象获取double
值:
public class Test implements DoubleSupplier {
private double a;
public Test(double a) { this.a = a; }
public double getAsDouble() { return 10 * a; }
public static double test(DoubleSupplier ds) {
return ds.getAsDouble();
}
public static void main(String[] args) {
double a = test(new Test(5));
}
}
如果您不使用Java 8,那么您可以通过以下方式创建自己的接口:
public interface MyDoubleSupplier {
double getAsDouble();
}
答案 1 :(得分:1)
你不会在Java中得到完全相同的东西,但你所做的事情的原则应该是一样的。
如果你想要一个可以像functor_obj()
那样调用的Java仿函数,那是不可能的。 Java不允许运算符重载*,因此这种语法根本不可能。
然而,Java 8引入了&#34; Functional Interfaces&#34;的概念,它被定义为任何具有一个[abstract **]功能的接口。只要您使用功能界面,就可以用lambda表达式替换它的实例化。
Runnable run = () -> {System.out.println("Hello World (FROM THE SECOND DIMEN—I mean THREAD)");};
Thread thread = new Thread(run);
//Also Equivalent to the two above lines:
//Thread thread = new Thread(() -> {System.out.println("Hello World (FROM THE SECOND DIMEN—I mean THREAD)");});
thread.start();
thread.join();
如果你想调用这个特殊的仿函数,你只需调用它就像实现接口的任何其他对象一样:
run.run();
因为Java Lambda表达式所做的是隐藏实现。以下代码:
Runnable run = () -> {System.out.println("Hello World (FROM THE SECOND DIMEN—I mean THREAD)");};
与Java 7等效代码相同:
Runnable run = new Runnable() {
public void run() {
System.out.println("Hello World (FROM THE SECOND DIMEN—I mean THREAD)");
}
};
因此,对于您的示例,您可能会写下这样的内容:
public static double test(Supplier<Double> f) {//imported from java.util.function
return f.get();
}
然后可以这样调用:
double a = test(() -> 25);
这相当于您在原始main
函数中编写的代码。如果您需要存储仿函数以供将来使用,您可以这样写:
Supplier<Double> sup = () -> 25;
double a = test(sup);
/*sup can now be stored somewhere or passed to a different function.*/
* - 我的意思是,Java DOES对String
个对象进行运算符重载以允许使用+
来连接对象,但这几乎是唯一的情况。使用过。
** - Java 8还引入了&#34;默认&#34;接口的方法,允许接口具有已实现的方法。这可能看起来很奇怪,直到你意识到它可以让你写public default void sort()
这样的东西,可以添加到java.util.List<T>
以允许所有具有访问器和删除操作的列表使用通用的,通用的算法
答案 2 :(得分:1)
在Java中没有确切的等价物,因为没有像在C ++中那样重载()
的含义。
从Java 8开始,您可以使用Java编写功能样式,并且包java.util.function
中有许多标准功能接口。
你可以这样做:
import java.util.function.DoubleSupplier;
public double test(DoubleSupplier supplier) {
return supplier.getAsDouble();
}
public DoubleSupplier newSupplier(double a) {
return () -> 10 * a;
}
// use it:
double a = test(newSupplier(5));