[英]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(例如
List
和Map
)。显然,这种特殊的语言功能不会很好地转换为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.