2017-04-26 60 views
0

试图将一些Java来我面对它在Java世界中编细不同的方法签名的问题Scala代码:将Java到Scala代码 - 方法签名的变化

在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

这是一个ImageGenerator问题,通过SparkImageGenerator继承。正如你所看到here,它有一个方法

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

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

斯卡拉不支持以任何方式原始类型的,所以你不能从它调用这个方法(据我所知)。作为一种解决方法,您可以在Java中编写一个使用正确类型的封装器并从Scala调用该封装器。我误解了,它扩展了扩展原始类型的Java类,这是不可能的,甚至有解决方法。

您可能能够通过明确的类型归属(最好铸造)来称呼它:

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

但提供的错误消息却与此JavaPairRDD,我不是特别期望它的工作。如果失败了,我仍然会使用Java包装器。

+0

我以为原始类型被解释为Scala中的存在类型。 –

+0

呃,你说得对,当然。问题是,在这个特定的情况下,它似乎没有这样解释它,因为错误消息显示它是一个原始类型('x $ 1:org.apache.spark.api.java.JavaPairRDD,...' )。 –

+0

我不确定如果这是错误消息或typechecker的问题。实际上我有一个拉取请求来改善一些关于原始类型的错误信息:https://github.com/scala/scala/pull/5847 –

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; 
    } 
} 

然后尝试从斯卡拉称之为:

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 

所以看起来必须有一些其他的问题。