जावा 8 विधि में स्कैला फ़ंक्शन पास करना


18

निम्नलिखित स्कैला कोड काम करता है और एक जावा विधि को पारित किया जा सकता है जो एक फ़ंक्शन की उम्मीद करता है। क्या ऐसा करने का कोई क्लीनर तरीका है? यहाँ मेरा पहला पास है:

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] = ???
}

यहाँ मेरा दूसरा पास है - यह जावा -8 फंक्शन इंटरफ़ेस के लिए एक सामान्य आवरण का उपयोग करता है, जो कि स्कैला सिंटैक्स को सरल बनाता है:

// 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)

क्या हम बेहतर कर सकते हैं?

अनुवर्ती के रूप में, क्या कोई मौका है कि स्काला किसी दिन चालान-डायनेमिक सेशन-कोड का उपयोग करेगा जैसा कि जावा 8 अपने प्रथम श्रेणी के फ़ंक्शन अनुप्रयोग के लिए करता है? क्या यह सब कुछ जादुई रूप से काम करेगा, या फिर भी एक सांकेतिक रूपांतरण होने की आवश्यकता होगी?

जवाबों:


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

आप वास्तव में ओवरराइड करने के लिए आवश्यकता नहीं होनी चाहिए composeऔर andThen, लेकिन शायद स्काला संकलक जावा 8 डिफ़ॉल्ट इंटरफ़ेस तरीकों के बारे में अभी तक पता नहीं है। (EDIT: इसे 2.10.3 में काम करना चाहिए।)

इसके अलावा, आपको स्कैला लैम्ब्डा (यानी x => ...) को Functionऔर स्कैला 2.11 में किसी भी अन्य एसएएम प्रकार, और जावा 8 लैम्बडा को असाइन करने में सक्षम होना चाहिए Function1। (EDIT: यह वास्तव में स्कैला 2.12 में जोड़ा गया, न कि 2.11 पर।)


you should be able to assign Scala lambdas- इसका मतलब यह है कि, स्कला 2.11 में, एक स्कैला फ़ंक्शन को Java8 लैम्ब्डा के तर्क के रूप में पारित किया जा सकता है?
केविन मेरेडिथ

क्या यह तर्क के रूप में पारित किया जा सकता है, यह लंबोदर के प्रकार पर निर्भर करता है; अगर यह उदा है java.util.function.Consumer[scala.Function1[Integer, String]]तो इसे 2.11 से पहले भी किया जा सकता है।
एलेक्सी रोमानोव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.