복붙노트

[SCALA] 자바에서 스칼라를 사용하여 다음 매개 변수로 함수를 전달

SCALA

자바에서 스칼라를 사용하여 다음 매개 변수로 함수를 전달

다음 스칼라 코드를 살펴 보자 :

package scala_java
object MyScala {
  def setFunc(func: Int => String) {
    func(10)
  }
}

이제 자바에서, 나는대로 MyScala를 사용하는 좋아했을 것입니다 :

package scala_java;
public class MyJava {
    public static void main(String [] args) {
        MyScala.setFunc(myFunc);  // This line gives an error
    }
    public static String myFunc(int someInt) {
        return String.valueOf(someInt);
    }
}

(프로그래밍 기능을 허용하지 않는 자바 때문에 예상대로) 그러나, 위의하지 작업을 수행합니다. 자바의 기능을 전달하는 가장 쉬운 해결 방법은 무엇입니까? 나는 함수는 매개 변수의 임의의 수를 갖는 작동하는 일반적인 솔루션을하고 싶습니다.

편집 :합니까 자바 (8)는 아래에 설명 고전적인 솔루션보다 더 나은 구문이?

해결법

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

    1.수동으로 자바의 기능 1을 인스턴스화해야합니다. 뭔가 같은 :

    수동으로 자바의 기능 1을 인스턴스화해야합니다. 뭔가 같은 :

    final Function1<Integer, String> f = new Function1<Integer, String>() {
        public int $tag() {
            return Function1$class.$tag(this);
        }
    
        public <A> Function1<A, String> compose(Function1<A, Integer> f) {
            return Function1$class.compose(this, f);
        }
    
        public String apply(Integer someInt) {
            return myFunc(someInt);
        }
    };
    MyScala.setFunc(f);
    

    이것은 다니엘 스피 웍의 "상호 운용성 자바와 스칼라 사이"기사에서 가져옵니다.

  2. ==============================

    2.scala.runtime 패키지에서 AbstractFunction1 이름 등 다른 arities에 대한 추상 클래스가 있습니다. 자바에서 그들을 사용하려면 당신은 단지 다음과 같이 적용 재정의해야합니다 :

    scala.runtime 패키지에서 AbstractFunction1 이름 등 다른 arities에 대한 추상 클래스가 있습니다. 자바에서 그들을 사용하려면 당신은 단지 다음과 같이 적용 재정의해야합니다 :

    Function1<Integer, String> f = new AbstractFunction1<Integer, String>() {
        public String apply(Integer someInt) {
            return myFunc(someInt);
        }
    };
    

    자바 8에있어이 자바 8 람다 구문을 사용하려면, https://github.com/scala/scala-java8-compat을 확인하십시오.

  3. ==============================

    3.나를 위해 가장 쉬운 방법은 자바 인터페이스와 같은 정의이다 :

    나를 위해 가장 쉬운 방법은 자바 인터페이스와 같은 정의이다 :

    public interface JFunction<A,B> {
      public B compute( A a );
    }
    

    다음 또한 JFunction가 같은 객체를 받아 setFunc 과부하, 당신의 스칼라 코드를 수정 :

    object MyScala {
      // API for scala
      def setFunc(func: Int => String) {
        func(10)
      }
      // API for java
      def setFunc(jFunc: JFunction[Int,String]) {
        setFunc( (i:Int) => jFunc.compute(i) )
      }
    }
    

    당신은 자연스럽게 스칼라에서 첫 번째 정의를 사용하지만, 여전히 자바에서 두 번째를 사용할 수 있습니다 :

    public class MyJava {
      public static void main(String [] args) {
        MyScala.setFunc(myFunc);  // This line gives an error
      }
    
      public static final JFunction<Integer,String> myFunc = 
        new JFunction<Integer,String>() {
          public String compute( Integer a ) {
            return String.valueOf(a);
          }
        };
    
    }
    
  4. ==============================

    4.여기에 솔루션에서 내 시도, 약간 라이브러리는 다음과 같습니다 https://github.com/eirslett/sc8

    여기에 솔루션에서 내 시도, 약간 라이브러리는 다음과 같습니다 https://github.com/eirslett/sc8

    당신은 F (...)에 자바 8 람다를 포장 한 다음은 스칼라 함수로 변환됩니다.

  5. from https://stackoverflow.com/questions/6545066/using-scala-from-java-passing-functions-as-parameters by cc-by-sa and MIT license