一个简单的单词计数程序。注解可以说是很详细了 。
public class SocketWordCount {
public static void main(String[] args)throws Exception {
// 获取执行环境
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
// 获取数据流,例子中是从指定端口的socket中获取用户输入的文本
DataStream<String> text = env.socketTextStream("localhost", 9999);
// transformation操作,对数据流实现算法
DataStream<WordWithCount> windowCounts = text
//将用户输入的文本流以非空白符的方式拆开来,得到单个的单词,存入命名为out的Collector中
.flatMap(new SplitString())
//将数据按照“word”分组,其实就是按照不同的单词分组。
//这个word和下面的“count”都是WordWithCount内定义的字段。
//这里也可以不用自定义WordWithCount,可以使用tuple。
//当然,要是使用tuple的话,在new SplitString()中,collector.collect的就得是Tuple类型了。
.keyBy("word")
//这个滚动窗口的计算,是每次计算5秒的数据(这个时间可以自己设置),
//第一个5秒和第二个5秒的数据没有任何关系。
//比如,第一个5秒,hello出现了10次,word出现了8次;第二个5秒,hello和word的出现次数会从0开始计算。
// .timeWindow(Time.seconds(5))
//滑动窗口机制,每2秒计算一次最近5秒的数据
.timeWindow(Time.seconds(5), Time.seconds(2))
//可以直接使用这个算子,计算单词出现次数
.sum("count");
//也可以使用reduce计算,sum更简便一些。
// .reduce(new ReduceFunction<WordWithCount>() {
// public WordWithCount reduce(WordWithCount a, WordWithCount b) {
// return new WordWithCount(a.word, a.count + b.count);
// }
// });
// 单线程执行该程序
windowCounts.print().setParallelism(1);
// windowCounts.writeAsText("/root/flink/output/wordcount.txt", WriteMode.NO_OVERWRITE).setParallelism(1);
//提交执行
env.execute();
}
public static class SplitString
implements FlatMapFunction<String, WordWithCount> {
private static final long serialVersionUID=1L;
@Override
public void flatMap(String s, Collector<WordWithCount> collector) {
for (String word : s.split(" ")) {
collector.collect(new WordWithCount(word, 1));
}
;
}
}
}
public class WordWithCount {
//两个变量存储输入的单词及其数量
public String word;
public long count;
//无参构造必须要有的
public WordWithCount() {}
public WordWithCount(String word, long count) {
this.word = word;
this.count = count;
}
@Override
public String toString() {
return "[ " + word + " : " + count +" ]";
}
}
感谢各位大佬前来。