복붙노트

[SCALA] 스칼라에서 자바 람다를 사용하는 방법

SCALA

스칼라에서 자바 람다를 사용하는 방법

나는 다음과 같은 코드가 있습니다 :

source
    .mapValues(value -> value + " Stream it!!!")
    .print(Printed.toSysOut());

당신이 볼 수 있듯이, mapValues는 람다 식을 기대하고있다.

지금, 나는 자바 라이브러리를 사용하고 있지만 응용 프로그램은 스칼라로 작성된 것입니다. 어떻게 자바 코드로 스칼라 람다를 전달하는?

나는 다음을 시도 :

source
  .mapValues(value => value + "hello")
  .print(Printed.toSysOut)

그러나 컴파일러는 불평 :

[error]   (x$1: org.apache.kafka.streams.kstream.Printed[String,?0(in value x$1)])Unit <and>
[error]   (x$1: org.apache.kafka.streams.kstream.KeyValueMapper[_ >: String, _ >: ?0(in value x$1), String])Unit <and>
[error]   (x$1: String)Unit
[error]  cannot be applied to (org.apache.kafka.streams.kstream.Printed[Nothing,Nothing])
[error]       .print(Printed.toSysOut)
[error]        ^
[error] two errors found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 2 s, completed Nov 19, 2017 7:53:44 PM

해결법

  1. ==============================

    1.오류 메시지 목록 지원을 인쇄 인수의 유형. 그 중 하나입니다 :

    오류 메시지 목록 지원을 인쇄 인수의 유형. 그 중 하나입니다 :

    org.apache.kafka.streams.kstream.Printed[String,?0(in value x$1)]
    

    오류 메시지에서 당신은 당신의 유형 Printed.toSysOut를 제공하고 있음을 볼 수있다 :

    org.apache.kafka.streams.kstream.Printed[Nothing,Nothing]
    

    카프카 1에 따른 자바 독 (인쇄 카프카 1.1에 존재하지 않았다) toSysOut과 같이 정의된다 :

    public static <K,V> Printed<K,V> toSysOut()
    

    응답 문제 그래서 스칼라는 아무것도의 종류와 K와 V를 추론된다는 것이다. 명시 적 유형을 제공해야합니다.

    다음은 아마 작동합니다 :

    source
      .mapValues[String](value -> value + " Stream it!!!")
      .print(Printed.toSysOut[String,String])
    
  2. ==============================

    2.그것은 스칼라의 버전에 따라 달라집니다.

    그것은 스칼라의 버전에 따라 달라집니다.

    자바 기능은 반대의 예상과 반대되는 경우 2.12에서 스칼라 함수는 장소에서 사용할 수 있습니다.

    App1.java

    import java.util.function.Function;
    
    public class App1 {
        public static void method(Function<String, String> function) {
            System.out.println(function.apply("a"));
        }
    
        public static void main(String[] args) {
            App.method1((String s) -> s.toUpperCase());
        }
    }
    

    App.scala

    object App {
      def main(args: Array[String]): Unit = {
        App1.method((s: String) => s.toUpperCase)
      }
    
      def method1(function: String => String): Unit = {
        println(function("xyz"))
      }
    }
    

    2.11에서는 스칼라 - java8-의 compat를 사용할 수 있습니다

    libraryDependencies += "org.scala-lang.modules" %% "scala-java8-compat" % "0.8.0"
    

    App1.java

    import java.util.function.Function;
    import static scala.compat.java8.JFunction.func;
    
    public class App1 {
        public static void method(Function<String, String> function) {
            System.out.println(function.apply("a"));
        }
    
        public static void main(String[] args) {
            App.method1(func((String s) -> s.toUpperCase()));
        }
    }
    

    App.scala

    import scala.compat.java8.FunctionConverters._
    
    object App {
      def main(args: Array[String]): Unit = {
        App1.method(((s: String) => s.toUpperCase).asJava)
      }
    
      def method1(function: String => String): Unit = {
        println(function("xyz"))
      }
    }
    

    또한 2.11 스칼라에서 당신은 java.util.function.Function와 scala.Function1 사이의 암시 적 컨버터를 정의 할 수 있습니다.

    당신은 2.11 시도를 사용한다면

    source
      .mapValues((value => value + "hello").asJava)
      .print(Printed.toSysOut) 
    

    또는

    source
      .mapValues(((value: String) => value + "hello").asJava)
      .print(Printed.toSysOut[String, String])
    
  3. from https://stackoverflow.com/questions/47380774/how-to-use-java-lambdas-in-scala by cc-by-sa and MIT license