Что является самым простым способом реализации Scala PartialFunction в Java?

Для взаимодействия, мне нужно передать Scala PartialFunction из Java-кода. Для функции (Function1 и т.д.) Существует функция AbstractFunction, которую я могу подклассифицировать анонимным типом, но что было бы самым простым способом сделать то же самое для PartialFunction?

В этом случае я был бы рад, если бы это была "полная" функция в Java, отображаемая для всех значений, но введенная как PartialFunction.

Ответ 2

Что бы я сделал здесь, это предоставить интерфейс в Java, в какой-то общей библиотеке (которая не является scala -aware):

//this is Java - in the Java lib
abstract class PartialTransformer<I, O> {
    abstract public boolean isDefinedAt(I i);
    public O transform(I i) {
        if (isDefinedAt(i)) {
            return transform0(i);
        }
        return null;
    }
    abstract protected O transform0(I i);
}

Затем в scala (т.е. библиотека scala, зависящая от указанной выше библиотеки Java), преобразуйте ее реализацию в PartialFunction:

//this is scala - in the scala lib
object MyPartialFunctions {
  def fromPartialTransformer[I, O](t: PartialTransformer[I, O]) = new PartialFunction[I, O] {
    def isDefinedAt(i: I) = t isDefinedAt i
    def apply(i: I) = {
      val r = t transform i
      if (r eq null) throw new MatchError
      else r
    }
  }
}

Тогда ваш код Java может сделать это:

//This is Java - in your client code
MyPartialFunctions$.MODULE$.fromPartialTransformer(new PartialTransformer<Integer, String>() {
    @Override public boolean isDefinedAt(Integer i) { /* */ }
    @Override protected String transform0(Integer i) { /* */ }
}

Если вам не нравится синтаксис MyPartialFunctions$.MODULE$, это возможно в библиотеке scala, классе Java, который скрывает это от вас:

//This is Java - in the scala-lib
public class ScalaUtils {
    public <I, O> scala.PartialFunction<I, O> toPartialFunction(PartialTransformer<I, O> t) {
         MyPartialFunctions$.MODULE$.fromPartialTransformer(t);
    }
}

Затем ваш сайт будет выглядеть так:

//This is Java - in your client code
ScalaUtils.toPartialFunction(new PartialTransformer<Integer, String>() {
    @Override public boolean isDefinedAt(Integer i) { /* */ }
    @Override protected String transform0(Integer i) { /* */ }
}

Это включает в себя, гм, несколько уровней косвенности!