2016-09-29 76 views
3

我想transform()一個Dataset在Java中,如下所示:什麼是寫scala.Function1作爲lambda的正確方法?

Function1<Dataset<Long>,Dataset<Long>> withDoubled = (Dataset<Long> numbers) -> numbers.withColumn("doubled",numbers.col("id").multiply(2)); 
spark.range(10).transform(withDoubled).show(); 

然而,Function1<>被標記爲錯誤說有多個抽象函數重載。我如何將它寫成lambda?

回答

1

與Scala的Function1使用拉姆達的是不是straigt前進,爲lambda與只有一個abstract未實現的功能,這是不正確的Scala的Function1特質的情況下Interface的工作。

我們可以用一個變通方法是,

首先讓定義的建設者,這使得失業各地可重複使用,

生成器Function1

package lambdascala; 

import scala.Function1; 

public class Function1WithLambdaBuilder<P1, R> { 

    public static interface Function1LambdaApply<P1, R> { 
    R apply(P1 p1); 
    } 

    private Function1LambdaApply<P1, R> lambda; 

    private Function1<P1, R> function; 

    public Function1WithLambdaBuilder(Function1LambdaApply<P1, R> lambda) { 
    this.lambda = lambda; 
    this.function = new Function1<P1, R>() { 
     @Override 
     public R apply(P1 p1) { 
     return Function1WithLambdaBuilder.this.lambda.apply(p1); 
     } 
    }; 
    } 

    public Function1<P1, R> getFunction() { 
    return this.function; 
    } 

} 

另一個建設者Function2

package lambdascala; 

import scala.Function2; 

public class Function2WithLambdaBuilder<P1, P2, R> { 

    public static interface Function2LambdaApply<P1, P2, R> { 
    R apply(P1 p1, P2 p2); 
    } 

    private Function2LambdaApply<P1, P2, R> lambda; 

    private Function2<P1, P2, R> function; 

    public Function2WithLambdaBuilder(Function2LambdaApply<P1, P2, R> lambda) { 
    this.lambda = lambda; 
    this.function = new Function2<P1,P2, R>() { 
     @Override 
     public R apply(P1 p1, P2 p2) { 
     return Function2WithLambdaBuilder.this.lambda.apply(p1, p2); 
     } 
    }; 
    } 

    public Function2<P1, P2, R> getFunction() { 
    return this.function; 
    } 

} 

您可以按照相同的模式添加更多FunctionN的建設者。

現在我們可以使用這些助建Function1Function2

import lambdascala.Function1WithLambdaBuilder; 
import lambdascala.Function2WithLambdaBuilder; 
import scala.Function1; 
import scala.Function2; 
import java.util.List; 

public class LambdaTry { 

    public static void main() { 

    Function1<List<Long>, List<Long>> changeNothing = 
     new Function1WithLambdaBuilder<List<Long>, List<Long>>(
     // your lambda 
     (List<Long> list) -> list 
    ).getFunction(); 

    Function1<Integer, Integer> add2 = 
     new Function1WithLambdaBuilder<Integer, Integer>(
     // your lambda 
     (Integer i) -> i + 2 
    ).getFunction(); 

    Function2<Integer, Integer, Integer> add = 
     new Function2WithLambdaBuilder<Integer, Integer, Integer>(
     // your lambda 
     (Integer i, Integer j) -> i + j 
    ).getFunction(); 

    System.out.println(add2.apply(12)); 

    System.out.println(add.apply(12, 24)); 

    } 

} 
+1

您可以爲每種類型的單'static'工廠方法替換這些令人費解的建設者,使用標準的'Function'和'BiFunction'接口作爲輸入而不是定義其他接口。 – Holger

+0

@Holger OP希望使用lambda函數創建'scala.Function1','scala.Function2','scala.Function3'等實例。因爲他正在使用這些實例和其他一些需要'scala.Function1' ...實例的API,所以我沒有看到'Function'或'BiFunction'如何提供幫助。你可以使用這些發佈答案嗎? –

+1

只需將'Function1LambdaApply '替換爲'Function '和'Function2LambdaApply ''BiFunction '。對於三參數函數沒有內置類型,但是您沒有爲三個參數發佈示例。 – Holger

相關問題