簡體   English   中英

美元符號使用Spark SQL在Java中調用函數

[英]Dollar sign in function call in Java using Spark SQL

我有以下代碼(Java與Spark SQL) -

    import static org.apache.spark.sql.functions.col;
    ...

    System.out.println("=== Filtering records with average age more than 20 ===");
    Dataset<Row> result = df.filter(col("age").$less(20));

我從來沒有遇到過以美元開頭的Java函數調用。 嘗試谷歌搜索它,但我到目前為止最好的猜測是,它是Java調用Scala代碼的結果(但在Scala源代碼中沒有$ less函數)

能否為此提供一個可靠的解釋?

答案可以在這里找到 - http://www.codecommit.com/blog/java/interop-between-java-and-scala

運算符是方法

Java和Scala之間最明顯的區別之一是Scala支持運算符重載。 事實上,Scala支持運算符重載的變體,它比C ++,C#甚至Ruby提供的任何東西都強大得多。 除極少數例外情況外,任何符號都可用於定義自定義運算符。 這為DSL提供了極大的靈活性,甚至提供了平均每天的API(例如ListMap )。

顯然,這種特殊的語言功能不會很好地轉換為Java。 Java不支持任何變種的運算符重載,更不用說Scala定義的超強形式。 因此,必須在字節碼級別將Scala運算符編譯為完全非符號形式,否則Java互操作將無法修復,JVM本身將無法吞下結果。

決定此轉換的一個好的起點是在Scala中聲明運算符的方式:作為方法。 每個Scala運算符(包括像!這樣的一元運算符)都被定義為類中的方法:

 abstract class List[+A] { def ::[B >: A](e: B) = ... def +[B >: A](e: B) = ... } 

由於Scala類成為Java類,而Scala方法成為Java方法,因此最明顯的轉換是采用每個運算符方法並生成具有重翻譯名稱的相應Java方法。 實際上,這正是Scala所做的。 上面的類將編譯成相當於這個Java代碼:

 public abstract class List<A> { public <B super A> List<B> $colon$colon(B e) { ... } public <B super A> List<B> $plus(B e) { ... } } 

Scala的方法語法中的每個允許符號都具有“ $trans ”形式的相應轉換。 支持的翻譯列表是您希望在Scala網站上找到的那些文檔之一。 然而,唉,它缺席了。 以下是我所知道的所有翻譯的表格:

 ┌────────────────┬─────────────┐ │ Scala Operator │ Compiles To │ ├────────────────┼─────────────┤ │ = │ $eq │ ├────────────────┼─────────────┤ │ > │ $greater │ ├────────────────┼─────────────┤ │ < │ $less │ ├────────────────┼─────────────┤ │ + │ $plus │ ├────────────────┼─────────────┤ │ - │ $minus │ ├────────────────┼─────────────┤ │ * │ $times │ ├────────────────┼─────────────┤ │ / │ div │ ├────────────────┼─────────────┤ │ ! │ $bang │ ├────────────────┼─────────────┤ │ @ │ $at │ ├────────────────┼─────────────┤ │ # │ $hash │ ├────────────────┼─────────────┤ │ % │ $percent │ ├────────────────┼─────────────┤ │ ^ │ $up │ ├────────────────┼─────────────┤ │ & │ $amp │ ├────────────────┼─────────────┤ │ ~ │ $tilde │ ├────────────────┼─────────────┤ │ ? │ $qmark │ ├────────────────┼─────────────┤ │ | │ $bar │ ├────────────────┼─────────────┤ │ \\ │ $bslash │ ├────────────────┼─────────────┤ │ : │ $colon │ └────────────────┴─────────────┘ 

使用此表,您應該能夠派生任何Scala運算符的“真實名稱”,允許在Java中使用它。 當然,想法解決方案將是Java實際上支持運算符重載並且可以直接使用Scala的運算符,但不知何故我懷疑這種情況會很快發生。

****這個答案是由某人發布的,但出於某種原因被刪除了(如果答案的原始所有者可以重新發布,會很喜歡)

因為Scala的方法語法中的每個允許符號都具有“$ trans”形式的相應轉換。 所以對於你的問題,scala中有一個方法叫做<並且java中的相應方法將是$less

其他運營商將編譯為:

╔═══════════════════╦══════════════╗
║ Scala Operator    ║ Compiles To  ║
╠═══════════════════╬══════════════╣
║=                  ║$eq           ║
║>                  ║$greater      ║
║<                  ║$less         ║
║+                  ║$plus         ║
║-                  ║$minus        ║
║*                  ║$times        ║
║/                  ║$div          ║
║!                  ║$bang         ║
║@                  ║$at           ║
║#                  ║$hash         ║
║%                  ║$percent      ║
║^                  ║$up           ║
║&                  ║$amp          ║
║~                  ║$tilde        ║
║?                  ║$qmark        ║
║║                  ║$bar          ║
║\                  ║$bslash       ║
║:                  ║$colon        ║
╚═══════════════════╩══════════════╝

有關這方面的更多信息,請訪問: http//www.codecommit.com/blog/java/interop-between-java-and-scala

暫無
暫無

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

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