将java转换为scala代码 - 更改方法签名

时间:2017-04-26 05:51:10

标签: java scala overloading raw-types

尝试将一些java转换为scala代码我遇到了一个在java世界中编译得很好的不同方法签名的问题:

以下java代码(来自https://github.com/DataSystemsLab/GeoSpark/blob/master/babylon/src/main/java/org/datasyslab/babylon/showcase/Example.java#L122-L126

visualizationOperator = new ScatterPlot(1000,600,USMainLandBoundary,false,-1,-1,true,true);
visualizationOperator.CustomizeColor(255, 255, 255, 255, Color.GREEN, true);
visualizationOperator.Visualize(sparkContext, spatialRDD);
imageGenerator = new SparkImageGenerator();
imageGenerator.SaveAsFile(visualizationOperator.distributedVectorImage, "file://"+outputPath,ImageType.SVG);

已翻译为https://github.com/geoHeil/geoSparkScalaSample/blob/master/src/main/scala/myOrg/visualization/Vis.scala#L45-L57

val vDistributedVector = new ScatterPlot(1000, 600, USMainLandBoundary, false, -1, -1, true, true)
vDistributedVector.CustomizeColor(255, 255, 255, 255, Color.GREEN, true)
vDistributedVector.Visualize(s, spatialRDD)
sparkImageGenerator.SaveAsFile(vDistributedVector.distributedVectorImage, outputPath + "distributedVector", ImageType.SVG)

会抛出以下错误:

overloaded method value SaveAsFile with alternatives:
[error]   (x$1: java.util.List[String],x$2: String,x$3: org.datasyslab.babylon.utils.ImageType)Boolean <and>
[error]   (x$1: java.awt.image.BufferedImage,x$2: String,x$3: org.datasyslab.babylon.utils.ImageType)Boolean <and>
[error]   (x$1: org.apache.spark.api.java.JavaPairRDD,x$2: String,x$3: org.datasyslab.babylon.utils.ImageType)Boolean
[error]  cannot be applied to (org.apache.spark.api.java.JavaPairRDD[Integer,String], String, org.datasyslab.babylon.utils.ImageType)
[error]     sparkImageGenerator.SaveAsFile(vDistributedVector.distributedVectorImage, outputPath + "distributedVector", ImageType.SVG)

不幸的是,我不确定如何修复此问题/如何在scala中正确调用该方法。

2 个答案:

答案 0 :(得分:2)

这是由ImageGenerator继承的SparkImageGenerator中的问题。正如您所见here,它有一个方法

public boolean SaveAsFile(JavaPairRDD distributedImage, String outputPath, ImageType imageType)

使用原始类型(JavaPairRDD没有<...>)。它们的存在主要是为了与Java 5之前的代码和shouldn't normally be used otherwise兼容。对于这段代码,肯定没有充分的理由,因为它实际上需要特定的类型参数。使用原始类型只会失去类型安全性。也许某些子类(当前或潜在的)可能会覆盖它并期望不同的类型参数,但这将是对继承的误用,并且必须有更好的解决方案。

Scala不以任何方式支持原始类型,因此您无法从中调用此方法(AFAIK)。作为一种解决方法,你可以在Java中编写一个使用正确类型的包装器并从Scala调用这个包装器。我记错了,它扩展了Java类扩展原始类型,这是不可能的,甚至还有解决方法

您可以通过显式类型归属(最好是强制转换)来调用它:

sparkImageGenerator.SaveAsFile(
  (vDistributedVector.distributedVectorImage: JavaPairRDD[_, _]), 
  outputPath + "distributedVector", ImageType.SVG)

但鉴于错误消息仅显示JavaPairRDD,我并不特别期望它能够正常运行。如果失败了,我仍然会使用Java包装器。

答案 1 :(得分:2)

接受的答案是正确的,说应该避免原始类型。但是,Scala 可以与具有原始类型的Java代码进行互操作。 Scala将原始类型java.util.List解释为存在类型java.util.List[_]

以Java代码为例:

// Test.java
import java.util.Map;

public class Test {
  public boolean foo(Map map, String s) {
    return true;
  }
}

然后尝试从Scala调用它:

Welcome to Scala 2.12.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_131).
Type in expressions for evaluation. Or try :help.

scala> import java.util.{Map,HashMap}
import java.util.{Map,HashMap}

scala> new Test().foo(new HashMap[String,Integer], "a")
res0: Boolean = true

scala> val h: Map[_,_] = new HashMap[String,Integer]
h: java.util.Map[_, _] = {}

scala> new Test().foo(h, "a")
res1: Boolean = true

所以看起来一定有其他一些问题。