簡體   English   中英

Scala-> Java,將函數作為參數傳遞給另一個函數

[英]Scala -> Java , Pass function as a parameter to another function

我正在探索scala和Java 1.8,但無法在Java 1.8 Lambda表達式中找到等效的代碼。

Scala代碼:

object Ex1 extends App {

  def single(x:Int):Int =x
  def square(x:Int):Int = x * x
  def cube(x:Int):Int = x*x*x

  def sum(f:Int=>Int,a:Int,b:Int):Int=if (a>b) 0 else f(a) + sum(f,a+1,b)

  def sumOfIntegers(a:Int,b:Int)=sum(single,a,b)
  def sumOfSquares(a:Int,b:Int)=sum(square,a,b);
  def sumOfCubes(a:Int,b:Int)=sum(cube,a,b);

  println(sumOfIntegers(1,4));
  println(sumOfSquares(1,4));
  println(sumOfCubes(1,4));

}

output:

10
30
100

Java的

public class Test1{
    public int single(int x){
        return x;
    }
    public int square(int x){
        return x * x;
    }
    public int cube(int x){
        return x * x * x;
    }
    // what's next? How to implement sum() method as shown in Scala?
    // Stuck in definition of this method, Stirng s should be function type.
    public int sum( Sring s , int a, int b){
        // what will go here?
    }
    public int sumOfIntegers(int a, int b){
        return sum("single<Function> how to pass?",a,b);
    }
    public int sumOfSquares(int a, int b){
        return sum("square<Function> how to pass?",a,b);
    }
    public int sumOfCubes(int a, int b){
        return sum("cube<Function> how to pass?",a.b);
    }
}

使用JDK 1.8是否可以實現相同的目的?

對的,這是可能的:

 public Integer sumSingle(Integer a) { return a; }

 public int sum(Function<Integer, Integer> f, int a, int b)
 {
      ... : f.apply(a+1); // or whatever
 }

 public int sumOfIntegers(int a, int b)
 {
     return sum(Test1::single, a, b);
 }

構造Class::method從該方法創建一個Function對象。 或者,如果您不需要重用它,則可以直接傳遞一個參數: (Integer a) -> a*a* ...

Function<Integer, Integer> single = x -> x;
Function<Integer, Integer> square = x -> x*x;

public int sum( Function<Integer, Integer> s , int a, int b){
    if (a>b){
        return 0;
    } else {
        s.apply(a) + sum(s,a+1,b)
    }
}

您將需要定義將要使用的方法。 Java附帶的唯一一個Function<X,Y>Function<X,Y> (與Integer一起使用),可用於singlesquarecubeBiFunction<T,Y, R>可以用於三個sumOf

interface Sum {
    Integer apply(Function<Integer, Integer> func, int start, int end);
}

single,square和cube可以是類中的方法(請參閱cube或inline(請參閱其他兩個)。它們是Fuction 。然后可以將此函數傳遞給其他方法,並使用variableName.apply調用。

  class Test
{
    private static Integer sum(Function<Integer, Integer> func, int a, int b) {
        if (a>b)
            return 0;
        else return func.apply(a) + sum(func,a+1,b);
    }

    private static Integer cube(Integer a) {
        return a * a * a;
    }

    public static void main (String[] args) throws java.lang.Exception
    {

        Function<Integer,Integer> single = a -> a;
        Function<Integer,Integer> square = a -> a * a;
        Function<Integer,Integer> cube = Test::cube;

        // You can not do the sum in-line without pain due to its recursive nature.
        Sum sum = Test::sum;

        BiFunction<Integer, Integer, Integer> sumOfIntegers = (a, b) -> sum.apply(single, a, b);
        BiFunction<Integer, Integer, Integer> sumOfSquares = (a, b) -> sum(square, a, b); // You could just use the static method directly. 
        BiFunction<Integer, Integer, Integer> sumOfCubes = (a, b) -> sum(cube, a, b);

        System.out.println(sumOfIntegers.apply(1,4));
        System.out.println(sumOfSquares.apply(1,4));
        System.out.println(sumOfCubes.apply(1,4));
    }


}

在Java 8中,您可以使用任何功能接口 (即具有默認情況下僅具有一種非靜態方法的接口,而無需默認實現)來代替Scala的Function<N>類型。 java.util.function包中有很多這樣的接口,分別用於單參數和雙參數函數。 特別是對於使用int並返回int函數,您應該使用IntUnaryOperator ,它已經在其他人的評論中提到。 如果您有兩個以上的參數或兩個不同類型的參數,請使用一種方法定義自己的接口。 例如,使用3個參數的函數,這些參數采用intlonglong並返回一個非基元:

interface Fun3ILLO<T> {
    public T apply(int arg1, long arg2, long arg3);
}

(顯然,您可以選擇所需的接口和方法名稱)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM