💻

ScalaからJavaのlambdaを簡単に使う

2021/01/31に公開

ScalaからJavaのライブラリを使っていてJavaのlambdaを使いたいときかなり面倒なことになる。例としてJavaのOptional#mapをScalaから使うことを考える。

import java.util.Optional

object JavaLambda {
  def main(args: Array[String]) {
    val s = Optional.of("Scala")


    val l = s.map((s:String)=>s.concat("!!!")).get() // Error!!

    println(l)

  }
}

まずこれはコンパイルが通らない。Optional#mapがScalaの関数を受け付けない。動くようにするにはjava.util.functionを使ってJavaの無名クラスを作ることになる。

import java.util.Optional
import java.util.function.Function

object JavaLambda {
  def main(args: Array[String]) {
    val s = Optional.of("Scala")

    val mapper = new Function[String, String] {
      override def apply(v1: String):String = v1.concat("!!!")
    }

    val l = s.map(mapper).get()

    println(l)

  }
}

しかし,これはみっともない。これを解決するのにscala-java8-compatというライブラリがある。これを使うと次のように書ける。

import java.util.Optional
import scala.compat.java8.FunctionConverters._

object Java8Lambda {
  def main(args: Array[String]) {
    val s = Optional.of("Scala")

    val l = s.map(((v: String) => v.concat("!!!")).asJava).get()

    println(l)

  }
}

asJavaがJavaの無名関数クラスに適切に変換してくれる。

@FunctionalInterfaceにも適当に変換してくれるともっと楽なんだが。

GitHubで編集を提案

Discussion