Scala関数をJava 8メソッドに渡す


18

次の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-8Functionインターフェイスの汎用ラッパーを使用して、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はいつかJava 8がその一流の関数アプリケーションに使用するように、invoke-dynamicオペコードを使用する可能性はありますか?それはすべてを魔法のように機能させるのでしょうか、それとも構文変換が必要ですか?

回答:


10

変換を暗黙的にすることができます:

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

あなたが実際に上書きする必要はありませんcomposeandThen、多分ScalaのコンパイラはまだJavaの8デフォルトのインターフェイスメソッドを認識していません。(編集:2.10.3で動作するはずです。)

また、Scalaラムダ(つまりx => ...FunctionとScala 2.11の他のSAMタイプ、およびJava 8ラムダをに割り当てることができるはずFunction1です。(編集:これは実際には2.11ではなくScala 2.12で追加されました。)


you should be able to assign Scala lambdas-これは、Scala 2.11では、Scala関数をJava8 Lambdaの引数として渡すことができることを意味しますか?
ケビンメレディス

引数として渡すことができるかどうかは、ラムダの型によって異なります。例えばjava.util.function.Consumer[scala.Function1[Integer, String]]、それが2.11より前に行われる場合もあります。
アレクセイロマノフ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.