次のScalaコードは機能し、Javaメソッドを期待するメソッドに渡すことができます。これを行うためのよりクリーンな方法はありますか?これが最初のパスです。
val plusOne = new Java.util.function.Function[Int,Int] {
override def apply(t:Int):Int = t + 1
override def andThen[V](after:function.Function[_ >: Int, _ <: V]):
function.Function[Int, V] = ???
override def compose[V](before:function.Function[_ >: V, _ <: Int]):
function.Function[V, Int] = ???
}
これが私の2番目のパスです。Java-8関数インターフェイスの汎用ラッパーを使用してScala構文を単純化しています。
// Note: Function1 is Scala's functional interface,
// Function (without the 1) is Java 8's.
case class JavaFunction1[U,V](f:Function1[U,V]) extends Function[U,V] {
override def apply(t: U): V = f(t)
override def compose[T](before:Function[_ >: T, _ <: U]):
Function[T, V] = ???
override def andThen[W](after:Function[_ >: V, _ <: W]):
Function[U, W] = ???
}
val plusOne = JavaFunction1((x:Int) => x + 1)
val minusOne = JavaFunction1((x:Int) => x - 1)
もっと上手くできる?
フォローアップとして、Scalaがいつかinvoke-dynamic op-codeをJava 8がそのファーストクラスの関数に使用するように)使用する可能性はありますかアプリケーション?それはすべてを魔法のように機能させるでしょうか、それとも構文変換がまだ必要ですか?
変換を暗黙的にすることができます:
implicit def toJavaFunction[U, V](f:Function1[U,V]): Function[U, V] = new Function[U, V] {
override def apply(t: U): V = f(t)
override def compose[T](before:Function[_ >: T, _ <: U]):
Function[T, V] = toJavaFunction(f.compose(x => before.apply(x)))
override def andThen[W](after:Function[_ >: V, _ <: W]):
Function[U, W] = toJavaFunction(f.andThen(x => after.apply(x)))
}
implicit def fromJavaFunction[U, V](f:Function[U,V]): Function1[U, V] = f.apply
実際にcompose
とandThen
をオーバーライドする必要はありませんが、ScalaコンパイラはJavaまだ8つのデフォルトのインターフェースメソッド(編集:2.10.3で動作するはずです。)
また、Scala lambdas(つまりx => ...
)からFunction
およびScala 2.11、およびJava 8ラムダからFunction1
。 (編集:これは実際にはScala 2.12に追加され、2.11ではありません。)