我一直在Spark 2上开发很多东西,我正试图将我的代码库转移到Spark 3上。
问题是,我所有的lambda代码与数据集不再工作,引用Map是含糊不清的:
java: reference to map is ambiguous
both method <U>map(scala.Function1<T,U>,org.apache.spark.sql.Encoder<U>) in org.apache.spark.sql.Dataset and method <U>map(org.apache.spark.api.java.function.MapFunction<T,U>,org.apache.spark.sql.Encoder<U>) in org.apache.spark.sql.Dataset match
字符串
下面是一个在Spark3上复制它的快速代码:
public static void main(String[] args) {
SparkSession
.builder()
.master("local[1]")
.getOrCreate()
.createDataset(Arrays.asList("A", "b", "C"), Encoders.STRING())
// error is here
.map(v -> v.toLowerCase(), Encoders.STRING())
.show();
}
型
这个错误也适用于其他所有的数据集转换,如filter,flatMap,.
我尝试了不同版本的Java(8,11和17),但错误总是相同的。
在过去,我曾经用Intellij使用Scala插件遇到过类似的问题,但现在,即使是Java也无法用Spark3编译此代码。
它甚至不能与方法引用一起工作。唯一的修复是转换:
public static void main(String[] args) {
SparkSession
.builder()
.master("local[1]")
.getOrCreate()
.createDataset(Arrays.asList("A", "b", "C"), Encoders.STRING())
// A cast fixes the issue
.map((MapFunction<String, String>) v -> v.toLowerCase(), Encoders.STRING())
.show();
}
型
或者创建一个实现所需函数的类
public class Main {
public static void main(String[] args) {
SparkSession
.builder()
.master("local[1]")
.getOrCreate()
.createDataset(Arrays.asList("A", "b", "C"), Encoders.STRING())
.map(new LowerCaseSparkFunction(), Encoders.STRING())
.show();
}
}
class LowerCaseSparkFunction implements MapFunction<String, String> {
@Override
public String call(String s) throws Exception {
return s.toLowerCase();
}
}
型
我发现铸造解决方案太冗长,我需要更新很多代码才能让它工作。还有其他解决方案吗?
1条答案
按热度按时间lg40wkob1#
一个小的助手函数家族(或使用Scala),例如:
字符串
是第三种选择,类型推断将得到改进,而你最困难的任务是记住函数名和导入。
为源代码中的每个歧义添加一个静态函数到util类。