我需要做以下事情:使用Apache Spark流,对于文件中给定字符串中的每个单词,我希望有一个包含几个单词的字符串窗口,可以使用/打印到标准输出。到目前为止,我有以下代码:
SparkConf conf = new SparkConf()
.setAppName("SparkApp")
.setMaster("local[*]");
JavaSparkContext sc = new JavaSparkContext(conf);
JavaRDD<String> distFile = sc.textFile("file.txt");
JavaRDD<String> words = distFile
.flatMap(x -> Arrays.asList(
x.replaceAll(",", " ")
.replaceAll(""", " ")
.split(" ")).iterator());
words.foreach(x -> {
System.out.println(x);
});
文件file.txt如下所示:
The quick brown fox jumps over the lazy dog
程序的输出如下:
The
quick
brown
fox
jumps
over
the
lazy
dog
我想让它做的是,例如,如果我传递给某个方法3,让它以以下方式一次打印三个单词:
The quick brown
quick brown fox
brown fox jumps
fox jumps over
.. etecetera
到目前为止我尝试过的:
- 实现了一个可串行化的链表作为一个队列,在用.foreach传递每个单词时,将当前单词添加到其中,并将最后一个单词删除到中。它没有成功,因为显然你不能通过foreach RDD来更改局部变量
- 发现了一些有用的东西,类似于我应该做的关于数据流和数据滑动窗口的事情,但事实证明这非常困难,如果这确实是唯一的方法,或者确实有更好的方法,我真的宁愿在深入研究之前听听你们的意见
您想要一个函数,它接受一个字符串,并返回一个包含N个令牌的字符串列表
def splitNum(line: String, count: Int): List[String] = {
line
.split(" ") // break into tokens
.grouped(count) // group every COUNT tokens together
.map { tokens =>
tokens.mkString(" ") // glue group of tokens back together
}
}
然后,您可以将该函数应用于您读取的文本,如:
distFile.flatMap(line => splitNum(line, 3))
根据文本文件的干净程度,您可能还有其他工作要做,比如处理其他标点符号、更好的标记化、处理多个空格等