Конечно, есть много способов сделать это. Вот 2:
Один: плоская карта и создание фрейма данных:
JavaRDD<Row> rowRdd = spark.read()
.textFile("loremipsum.txt")
.javaRDD()
.flatMap(s -> Arrays.asList(s.split(" ")).iterator())
.map(s -> RowFactory.create(s));
spark.createDataFrame(rowRdd,
new StructType()
.add(DataTypes.createStructField("word", DataTypes.StringType, true)))
.groupBy("word")
.count()
.show();
Печать что-то вроде:
+------------+-----+
| word|count|
+------------+-----+
| Sit| 17|
| Elit| 6|
| vehicula.| 2|
| eros.| 2|
| nam.| 3|
| porttitor| 18|
|consectetur.| 6|
...
Бонус: используйте SQL группировать (если это считается еще одной альтернативой)
Два: группировать по словам и считать элементы в итерациях:
Map<String, Long> counts = spark.read().textFile("loremipsum.txt")
.javaRDD()
.flatMap(s -> Arrays.asList(s.split(" ")).iterator())
.groupBy(i -> i)
.aggregateByKey(0L, (id, it) -> countIterable(it), (a, b) -> a + b)
.collect() //collection of Tuple2: you can stop here
.stream()
.collect(Collectors.toMap(t -> t._1, t -> t._2));
В результате получается что-то вроде:
{=50, Malesuada=4, justo.=3, potenti=2, vel.=11, purus=30, curabitur.=2...}
с countIterable
определяется как:
private static <T> long countIterable(Iterable<T> it) {
long res = 0;
for (T t : it)
res += 1;
return res;
}
, который также может быть реализован как
return StreamSupport.stream(it.spliterator(), false).count();