49

次の Scala コードを検討してください。

package scala_java
object MyScala {
  def setFunc(func: Int => String) {
    func(10)
  }
}

今Javaでは、次のように使用したかったでしょうMyScala

package scala_java;
public class MyJava {
    public static void main(String [] args) {
        MyScala.setFunc(myFunc);  // This line gives an error
    }
    public static String myFunc(int someInt) {
        return String.valueOf(someInt);
    }
}

ただし、上記は機能しません (Java では関数型プログラミングが許可されていないため、予想どおり)。Javaで関数を渡す最も簡単な回避策は何ですか? 任意の数のパラメーターを持つ関数で機能する一般的なソリューションが必要です。

編集: Java 8 には、以下で説明する従来のソリューションよりも優れた構文がありますか?

4

4 に答える 4

74

パッケージには、他のアリティのscala.runtime名前などの抽象クラスがあります。Java からそれらを使用するには、次のようAbstractFunction1にオーバーライドするだけです。apply

Function1<Integer, String> f = new AbstractFunction1<Integer, String>() {
    public String apply(Integer someInt) {
        return myFunc(someInt);
    }
};

Java 8 を使用していて、これに Java 8 ラムダ構文を使用したい場合は、https://github.com/scala/scala-java8-compatを確認してください。

于 2011-12-05T03:29:04.310 に答える
27

Function1Javaで a を手動でインスタンス化する必要があります。何かのようなもの:

final Function1<Integer, String> f = new Function1<Integer, String>() {
    public int $tag() {
        return Function1$class.$tag(this);
    }

    public <A> Function1<A, String> compose(Function1<A, Integer> f) {
        return Function1$class.compose(this, f);
    }

    public String apply(Integer someInt) {
        return myFunc(someInt);
    }
};
MyScala.setFunc(f);

これは、Daniel Spiewak の記事「Java と Scala の間の相互運用性」からの抜粋です。

于 2011-07-01T08:05:51.690 に答える
7

私にとって最も簡単な方法は、次のようなJavaインターフェイスを定義することです。

public interface JFunction<A,B> {
  public B compute( A a );
}

次に、次のようなオブジェクトsetFuncも受け入れるようにオーバーロードして、scala コードを変更します。JFunction

object MyScala {
  // API for scala
  def setFunc(func: Int => String) {
    func(10)
  }
  // API for java
  def setFunc(jFunc: JFunction[Int,String]) {
    setFunc( (i:Int) => jFunc.compute(i) )
  }
}

当然、scala の最初の定義を使用しますが、Java の 2 番目の定義を使用することもできます。

public class MyJava {
  public static void main(String [] args) {
    MyScala.setFunc(myFunc);  // This line gives an error
  }

  public static final JFunction<Integer,String> myFunc = 
    new JFunction<Integer,String>() {
      public String compute( Integer a ) {
        return String.valueOf(a);
      }
    };

}
于 2011-07-01T08:01:29.663 に答える