I would like to express all of the following Scala code in Java:
object TupleDemo {
val tuple = (3, "Hello, world! ")
/** @return str replicated x times */
def foo(x: Int, str: String) = str * x
val tupledFoo1 = (foo _).tupled // partially applied function
val tupledFoo2 = Function.tupled(foo _) // desugared syntax for same partially applied function
}
object TupleDemoApp extends App {
import TupleDemo._
println(tupledFoo1(tuple)) // Hello, world! Hello, world! Hello, world!
println(tupledFoo2(tuple)) // Hello, world! Hello, world! Hello, world!
}
This is as much as I could figure out for the Java equivalent:
import scala.Function1;
import scala.Function2;
import scala.Tuple2;
import scala.collection.immutable.WrappedString;
import scala.runtime.AbstractFunction2;
public class JavaTupleDemo {
/** @return str replicated x times */
static final Function2<Integer, String, String> foo = new AbstractFunction2<Integer, String, String>() {
public String apply(Integer x, String str) {
return new WrappedString(str).$times(x);
}
// perhaps the types for this method are incorrect?
public Function1<Tuple2<Integer, String>, String> tupled(Tuple2 tuple2) {
return null; // what to write here instead of null?
}
};
public static void main(String[] args) {
// works: Invoke tupled function defined in Scala from Java using Tuple2 defined in Java
Tuple2<Object, String> tuple = new Tuple2<Object, String>(3, "Hello, World! ");
System.out.println(TupleDemo.tupledFoo1().apply(tuple));
// works: Invoke regular function defined in Java from Java
System.out.println(JavaTupleDemo.foo.apply(3, "Hello, planet! "));
// stumped: Invoke tupled function defined in Java from Java using both the Scala and the Java Tuple2 instances
}
}
tupledis implemented inFunction2(and therefore inAbstractFunction2), so there’s no need to define it here—you can just write this:Note that we need to write
foo.tupled(), since Java sees this as a method, and that in both cases we get aFunction1, so we have to write.apply(tuple), but otherwise this is essentially the same as the Scala version.To address your question about getting the
Integerin the tuple typed as anObject: the easiest way to handle this (assuming you can’t or don’t want to make it anIntegerexplicitly on the Scala side) is probably the following:I.e., just take the tuple apart, cast the
Integer, and put it back together.