Apache SparkでMRジョブを使用して入力INの最大値を返すScalaクラスがあります。複数の暗黙のパラメータを持つプライマリコンストラクタをJavaから呼び出す
// Class
class TypedMax[IN, T](val f: IN => T)(implicit ev$1: T => Ordered[T], ev$2: TypeTag[T])
extends Aggregator[IN, T, T] {
override def zero: T = null.asInstanceOf[T]
override def reduce(b: T, a: IN): T = if (b > f(a)) b else f(a)
override def merge(b1: T, b2: T): T = if (b1 > b2) b1 else b2
override def finish(reduction: T): T = reduction
}
// Call function
def max[IN, T](f: IN => T)(implicit ev$1: T => Ordered[T], ev$2: TypeTag[T]): TypedColumn[IN, T] =
new TypedMax[IN, T](f).toColumn
今、私はJavaからこれも呼び出し可能したいと思いますが、私は暗黙のパラメータに渡すといくつかの困難が生じています:私はスカラ座からそれを呼び出すと、次のようにそれが動作する場合は、このクラスでは正常に動作します。暗黙的なパラメータは、Javaの引数リストに追加することで渡すことができますが、暗黙的なパラメータはScalaにあります。したがって、私は、次の操作を実行しようとしています:
その後、Javaから呼び出すことができますclass TypedMax[IN, T](val f: IN => T)(implicit ev$1: T => Ordered[T], ev$2: TypeTag[T])
extends Aggregator[IN, T, T] {
override def zero: T = null.asInstanceOf[T]
override def reduce(b: T, a: IN): T = if (b > f(a)) b else f(a)
override def merge(b1: T, b2: T): T = if (b1 > b2) b1 else b2
override def finish(reduction: T): T = reduction
// Java api support
def this(f: MapFunction[IN, java.lang.Double]) =
this(x => f.call(x).asInstanceOf[T])(ev$1: T => Ordered[T], ev$2: TypeTag[T])
:
public static <T> TypedColumn<T, Double> max(MapFunction<T, Double> f) {
return new TypedMax<T, Double>(f).toColumn();
}
私はimplicity
implicit
を使用して、補助コンストラクタから暗黙に渡すの多くの順列を試してみましたカンマとかっこで遊んでいます。しかし、それは常にev $ 1とev $ 2が見つからないと不平を言う。私がしようとした場合
Error:(135, 5) No implicit view available from T => Ordered[T].
this(x => f.call(x).asInstanceOf[T])
Error:(135, 5) not enough arguments for constructor TypedMax: (implicit ev$1: T => Ordered[T], implicit ev$2: reflect.runtime.universe.TypeTag[T])org.apache.spark.sql.execution.aggregate.TypedMax[IN,T].
Unspecified value parameters ev$1, ev$2.
this(x => f.call(x).asInstanceOf[T])
そして:私はそれ以外の場合はエラーになりますので、しかし、パラメータを渡す必要があり
def this(f: MapFunction[IN, T]) =
this(x => f.call(x))(T => Ordered[T], TypeTag[T])
結果は次のとおりです。
Error:(135, 38) value Ordered of type scala.math.Ordered.type does not take type parameters.
this(x => f.call(x))(T => Ordered[T], TypeTag[T])
Error:(135, 50) missing argument list for method apply in object TypeTag
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `apply _` or `apply(_,_)` instead of `apply`.
this(x => f.call(x))(T => Ordered[T], TypeTag[T])
私は何をしないのです/誤解? ありがとう!
おかげオリヴィエを(あなたがJavaから
TypeTag[T]
をマテリアライズすることができるようになるだろうしている場合、私は本当にわかりません)。そうです、私はタイプタグを実現できません。 私は現在、全体の問題を回避するために、その周りにラッパーを作成しようとしていますが、それでも動作していません。あなたはそれについて何か提案していますか? [入力、T](f:MapFunction [IN、T]){ def typedMax:TypedColumn [IN、T] = { 新しいTypedMax [IN、T](x => f.call(x) (Type [T]、TypeTag [T])を注文してください。toColumn } } 不幸にも不十分です – ScrubSクリーンな方法はありません、 'TypeTags'はscalacによって実現されています。サポートされている型は 'TypeTagForJava {def ttInt = TypeTag [Int]; ...} '。そうでなければ、リフレクションにフォールバックする必要があります。これはSparkが使用するものです。https://github.com/apache/spark/blob/master/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst /ScalaReflection.scala – OlivierBlanvillain