2016-08-17 14 views
1

は、C++でのファンクタの簡単な例を仮定します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でこの構成を実装する方法はありますか?簡単な例を教えてください。ご協力いただきありがとうございます。

+0

あり確認されています... –

+1

それはそれはあなたが*実際に*を達成しようとしている何であるかは不明です。これはラムダの単純なケースのようです。 – chrylis

+0

@ chrylis lambaなしでも可能ですか?機能が複雑になる可能性があります... – justik

答えて

2

、あなたがオブジェクトからdouble値を取得するためにDoubleSupplierインタフェースを使用することができます。

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を使用していない場合は、あなただけで実装する独自のインターフェースを作ることができます:あなたがC++で行うことができますよう()の意味をオーバーロードのような何もないよう

public interface MyDoubleSupplier { 
    double getAsDouble(); 
} 
+0

興味深い解決策、C++とはまったく異なるアプローチ:-) – justik

+0

実際、これはかなり似ています。 '()'を使って実行する代わりに '.getAsDouble()'を使って実行します。それ以外の場合は、同じ結果の構文と名前が少し異なります。 – 4castle

+0

私のコメントは、構文:-)を参照しています。あなたは正しいですが、結果は類似しています... – justik

1

あなたはJavaで全く同じことをするつもりはありませんが、あなたがやっていることの原則は同じでなければなりません。

functor_obj()のように呼び出すことができるファンクタをJavaで使用するには、これは不可能です。 Javaでは演算子のオーバーロードが許可されていない*ので、その種の構文は単純にできません。

しかし、Java 8では、「ファンクショナルインターフェイス」という概念が導入されました。これは、まさに1つの[抽象的な**]機能を持つインターフェイスとして定義されています。 Functional Interfaceで作業しているときはいつでも、インスタンス化をラムダ式に置き換えることができます。

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(); 

あなたは、この特定のファンクタを起動したい場合、あなたは単にあなたがインターフェイスを実装し、他のオブジェクトと同じ呼び出したい:どのようなJavaのラムダ式を行うことは非表示ですので

run.run(); 

は、実装。次のコード:

public static double test(Supplier<Double> f) {//imported from java.util.function 
    return f.get(); 
} 

:あなたの例のために、あなたはおそらくこのような何かを書きたい

Runnable run = new Runnable() { 
    public void run() { 
     System.out.println("Hello World (FROM THE SECOND DIMEN—I mean THREAD)"); 
    } 
}; 

ので:

Runnable run =() -> {System.out.println("Hello World (FROM THE SECOND DIMEN—I mean THREAD)");}; 

は、Java 7同等のコードと同じことを行いこのように呼び出すことができます:

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はへ+の使用を可能にしStringオブジェクトのための演算子オーバーロードを持っていますオブジェクトを連結することができますが、それはそれが使用される唯一の状況です。

** - Java 8では、インターフェイスに「デフォルト」メソッドが導入されました。これにより、インターフェイスでメソッドが実装されるようになりました。それは、アクセサーと削除操作を持つすべてのリストが共通の汎用アルゴリズムを使用してソートされるように、public default void sort()のようなものをjava.util.List<T>に追加することができるようになるまで、変わったように見えるかもしれません。Javaの8で

1

のJavaには、完全に同等ではありません。

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)); 
+0

@ Jasper:ソリューションをありがとう... – justik

関連する問題