上一篇文章中,使用了Scala开发了词频统计,本篇文章我们使用Java开发同样的词频统计,借以对比两门语言的不同。
数据依然存在于某个盘符文件下,具体看代码,内容是:
apple orange pear
banana lemon apple
pear peach orange
一、创建我们熟悉的Maven Java Module:
二、修改pom.xml
1,修改JDK为1.8
<maven.compiler.source>1.8</maven.compiler.source>
2,添加Spark依赖:
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.13</artifactId>
<version>3.2.0</version>
</dependency>
3,开发Java代码,具体看注释:
package com.alan;
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.*;
import scala.Tuple2;
import java.util.*;
import java.util.regex.Pattern;
public class Test1 {
public static void main(String[] args) {
SparkConf conf = new SparkConf().setAppName("WordCount").setMaster("local");
JavaSparkContext sparkContext = new JavaSparkContext(conf);
//读文件
JavaRDD<String> lines = sparkContext.textFile("d://test/words.txt").cache();
//读取行,并将单词成集合
JavaRDD<String> words = lines.flatMap(new FlatMapFunction<String, String>() {
@Override
public Iterator<String> call(String s) {
return Arrays.asList(s.split(" ")).iterator();
}
});
//map
JavaPairRDD<String, Integer> wordsOnes = words.mapToPair(new PairFunction<String, String, Integer>() {
@Override
public Tuple2<String, Integer> call(String s) {
return new Tuple2<String, Integer>(s, 1);
}
});
//reduce
JavaPairRDD<String, Integer> wordsCounts = wordsOnes.reduceByKey(new Function2<Integer, Integer, Integer>() {
@Override
public Integer call(Integer value, Integer toValue) {
return value + toValue;
}
});
//控制台打印
wordsCounts.foreach(new VoidFunction<Tuple2<String, Integer>>() {
@Override
public void call(Tuple2<String, Integer> tuple) throws Exception {
System.out.println( tuple._1()+" "+tuple._2());
}
});
// wordsCounts.saveAsTextFile("d:/test/spark_word");
}
}
从上可见有非常多的匿名内部类,伪函数式编程风格以及Scala的标识符语法,毕竟Spark是由Scala开发的,虽然Scala最终是编译成Java Class,但是在Spark下写Java,感觉是在去适用Scala。
如果精通Lambda,对其改写,代码会少点。