我是Spark API
的新手,并且一路学习。
我在hadoop目录中有多个文件,我正在使用WholeTextFiles读取这些文件来创建JavaPairRDD<String, String>
。程序使用Java。
我的要求是处理目录中的文件列表并实现以下输出:
文件路径,单词
文件路径,单词
文件路径,单词
...
这基本上是文件的单词内容,其文件名(或路径)配对为<String, String>
。
我尝试了以下操作,但是不允许将其从tuple2强制转换为Iterable(在运行时失败):
JavaSparkContext sc = new JavaSparkContext(new SparkConf()) ;
JavaPairRDD<String, String> files = sc.wholeTextFiles(args[0]);
JavaRDD<Tuple2<String, String>> file_word = files
.flatMap(new FlatMapFunction<Tuple2<String,String>, Tuple2<String,String>>()
{
public Iterable<Tuple2<String, String>> call(Tuple2<String, String> tuple)
{
return (Iterable<Tuple2<String, String>>) new Tuple2<String, Iterable<String>>(tuple._1(), Arrays.asList(((String) tuple._2()).toLowerCase ().split("\\W+")));
}
});
我正在将Java 8
和Hadoop2
与Spark 2.2.0
一起使用。
(通过在这里查看其他问题,我可以理解在scala中编写代码更容易,但是我没有找到Java的相关答案)
寻找解决方案。谢谢。
答案 0 :(得分:1)
据我所见,您正在尝试将Tuple2转换为Iterable,这无法正常工作。
由于您使用的是Java8,因此可以使用lambda表达式编写此代码,这会使事情变得更加紧凑:
tasksByTime.push(work);
请注意,我使用的是JavaPairRDD<String, String> rdd = sc
.wholeTextFiles("path_to_data/*")
.flatMapValues(x -> Arrays.asList(x.split("\\W+")));
而不是flatMapValues
,因为您只需要处理元组的第二个值。
如果您感到好奇,可以使用flatMap
通过将文件的每个单词映射到元组(文件名,单词)来实现:
flatmap
JavaRDD<Tuple2<String, String>> rdd2 = sc
.wholeTextFiles("path_to_data/*")
.flatMap(x -> Arrays.asList(x._2.split("\\n"))
.stream()
.map(w -> new Tuple2<>(x._1, w))
.iterator());
仅使您可以用更少的代码;-)