微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

互操作性:通过两种方式在Java和Scala之间共享对象或Row的数据集我在Java中间放置了一个Scala数据集操作

如何解决互操作性:通过两种方式在Java和Scala之间共享对象或Row的数据集我在Java中间放置了一个Scala数据集操作

目前,我的主应用程序是使用 Java Spring-boot 构建的,并且不会改变,因为它很方便。
@Autowired服务bean实现,例如:

  • 企业机构数据集。第一个还能够返回具有其场所Map Enterprise 对象的列表。
    因此服务返回:Dataset<Enterprise>Dataset<Establishment>Dataset<Row>
  • 关联:Dataset<Row>
  • 城市:Dataset<Commune>Dataset<Row>
  • 地方当局:Datatset<Row>

许多用例函数都是这种调用

什么是协会(year = 2020)?

然后我的应用程序转发到datasetAssociation(2020),该应用程序与企业和场所数据集以及城市和地方当局的数据集一起运行,以提供有用的结果。

许多建议我从 Scala 能力中受益

为此,我正在考虑涉及数据集之间其他操作的操作:

  • 一些由Row制成,
  • 一些携带混凝土物品的人。

就已到达/涉及的数据集而言,我需要执行此操作:
协会。企业。机构 .cities.localautorities

我可以在 Scala 中写粗体吗?这意味着:

  1. 使用 Java 代码构建的Dataset<Row>被发送到 Scala 函数以完成。

  2. Scala 使用EnterpriseEstablishment对象创建一个新的数据集。
    a)如果对象的源是用 Scala 编写的,则不必在 Java 中为其重新创建新的源。 /> b)相反,如果对象的源代码是用 Java 编写的,则不必在 Scala 中重新创建新的源代码
    c)我可以直接使用此数据集在 Java 端返回的 Scala 对象。

  3. Scala 将必须调用 Java 中保持实现的函数,并将其创建的基础数据集发送给它们(例如,使用城市信息来完善它们)。

Java 随时调用 Scala 方法
Scala 也会随时调用 Java 方法

操作可以遵循
Java -> Scala -> Scala -> Java -> Scala -> Java -> Java
如果需要,以所调用方法的本地语言表示。
因为我事先不知道我会发现哪些部分对在 Scala 中移植有用。

完成这三点后,我将认为 Java Scala 能够在两种方式下互操作,并从另一种方式中受益。

但是我是否可以实现这一目标(在Spark 2.4.x中或更可能在Spark 3.0.0中)?

总结一下,Java和Scala可以通过两种方式互操作,一种方式是:

  • 它不会使源代码的一方过于笨拙。甚至更糟:重复。
  • 它不会严重降低性能(例如,必须重新创建整个数据集或转换它包含的每个对象,例如,一侧或另一侧都是禁止的)。

解决方法

正如Jasper-M所写,scala和Java代码完全可以互操作:

  • 它们都编译成.vm文件,这些文件由jvm以相同的方式执行
  • spark java和scala API可以一起使用,但有一些细节:
    • 两者都使用相同的Dataset类,所以那里没有问题
    • 但是,SparkContext和RDD(以及所有RDD变体)具有scala api,这在Java中不实用。主要是因为scala方法将scala类型作为输入,而不是您在Java中使用的那些输入。但是它们都有Java包装器(JavaSparkContext,JavaRDD)。在Java中进行编码,您可能已经看到了这些包装器。

现在,正如许多人所建议的那样,首先将spark作为一个scala库,并且scala语言比Java(*)更强大,使用scala编写spark代码将更加容易。另外,您将在scala中找到更多代码示例。通常很难找到用于复杂数据集操作的Java代码示例。

因此,我认为您应该注意的两个主要问题是:

  1. (与火花无关,但有必要)有一个可以同时编译两种语言并允许双向互操作性的项目。我认为sbt是开箱即用的,使用maven时,您需要使用scala插件,并(根据我的经验)将java和scala文件都放在java文件夹中。否则,一个可以调用另一个,但是不能相反(scala调用java,但是java无法调用scala,或者相反)
  2. 您应注意每次创建类型化数据集(即Dataset[YourClass]而不是Dataset<Row>)时使用的编码器。在Java中,对于Java模型类,您需要显式使用Encoders.bean(YourClass.class)。但是在scala中,默认情况下,spark会隐式找到编码器,并且将为scala案例类(“产品类型”)和scala标准集合构建编码器。因此,请注意使用哪种编码器。例如,如果您在scala中创建YourJavaClass的数据集,我认为您可能必须明确给出Encoders.bean(YourJavaClass.class)才能使其起作用,而不会出现序列化问题。

最后一条说明:您写道使用Java Spring-boot。所以

  • 请注意,Spring设计完全违背scala /功能推荐的实践。遍历使用null和可变的东西。您仍然可以使用Spring,但在Scala中可能很奇怪,社区可能不会轻易接受它。
  • 您可以从spring上下文调用spark代码,但不应使用spark的spring(上下文),尤其是在spark分发的内部方法中,例如rdd.map中。这将尝试在每个工作程序中创建Spring上下文,这非常慢并且很容易失败。

(*)关于“ scala比Java更强大”:我并不是说scala比Java更好(我确实这么认为,但这是一个品味问题:)。我的意思是,scala语言比Java提供了更多的表达能力。基本上,用更少的代码即可完成更多工作。主要区别在于:

  • 隐式,Spark API大量使用
  • monad +理解力
  • 当然还有功能强大的类型系统(例如,有关协变量类型的信息,List [Dog]是scala中List [Animal]的子类,但在Java中不是)
,

是的,有可能不会导致性能下降或多余的多余代码。 Scala和Java几乎可以完全互操作,而且Spark Dataset API在Java和Scala之间共享。无论您使用Java还是Scala,Dataset类都是完全相同的。如您在javadocscaladoc中所见(请注意,它们仅在布局上有所不同,而在内容上没有区别),Java和Scala代码可以完美互换。最多Scala代码会更简洁。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。