在Flink中reduce
算子可以帮助我们实现很多计算需求,如最大值、最小值、求和等等,根据实际业务需求编写相关逻辑即可,下面将结合代码看一下reduce
算子如何使用.
-
测试数据
李淳风,男,风水大师,5000 李逵,男,健身教练,4500 袁天罡,男,风水大师,7000 张三丰,男,武术指导,6500 孙二娘,女,个体户,10000 孙悟空,男,动作演员,7000 司空震,男,电工,8000 吕布,男,武术指导,12000 貂蝉,女,法师,65000 俄洛伊,女,健身教练,5500
-
代码(获取不同性别中工资最高的那个人的信息)
import org.apache.flink.api.common.functions.MapFunction; import org.apache.flink.api.common.functions.ReduceFunction; import org.apache.flink.api.java.tuple.Tuple4; import org.apache.flink.streaming.api.datastream.DataStreamSource; import org.apache.flink.streaming.api.datastream.KeyedStream; import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; public class FlinkReduceDemo { public static void main(String[] args) throws Exception { // 创建流环境 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // 设置并行度,这里是为了结果数据更加直观 env.setParallelism(1); // 读取数据源 DataStreamSource<String> dataStream = env.readTextFile("data/test/userInfo.txt"); // 先将数据转成元组 SingleOutputStreamOperator<Tuple4<String, String, String, Integer>> mapStream = dataStream.map(new MapFunction<String, Tuple4<String, String, String, Integer>>() { @Override public Tuple4<String, String, String, Integer> map(String value) throws Exception { // 先将数据切分 String[] split = value.split(","); // 将切分后数据存如Tuple4(姓名, 性别, 职业, 工资)并返回 return Tuple4.of(split[0], split[1], split[2], Integer.parseInt(split[3])); } }); // 先将数据按照性别进行分组 KeyedStream<Tuple4<String, String, String, Integer>, String> keyByStream = mapStream.keyBy(tup -> tup.f1); // 这里使用reduce算子求出不同性别中工资最高的那个人 SingleOutputStreamOperator<Tuple4<String, String, String, Integer>> reduceStream = keyByStream.reduce(new ReduceFunction<Tuple4<String, String, String, Integer>>() { @Override public Tuple4<String, String, String, Integer> reduce(Tuple4<String, String, String, Integer> value1, Tuple4<String, String, String, Integer> value2) throws Exception { // 因为上面通过keyBy算子已经分好组了, 所以这里我们可以直接进行比较, 如果后面的人工资大于等于上一个人的工资则将整条数据进行更新替换 if (value1.f3 == null || value2.f3 >= value1.f3) { return value2; } else { // 如果不满足上面的条件则保留当前人员的信息 return value1; } } }); // 打印结果 reduceStream.print(); env.execute(); } }
-
结果数据
1> (李淳风,男,风水大师,5000) 2> (貂蝉,女,法师,65000) 1> (李淳风,男,风水大师,5000) 1> (袁天罡,男,风水大师,7000) 2> (貂蝉,女,法师,65000) 1> (袁天罡,男,风水大师,7000) 2> (貂蝉,女,法师,65000) 1> (孙悟空,男,动作演员,7000) 1> (司空震,男,电工,8000) 1> (吕布,男,武术指导,12000)
通过上面的结果可以看出来完全是按照我们在
reduce
算子中编写的逻辑得到的结果,当然求取最大值也可以使用max
和maxBy
算子,开发中还是要根据实际的业务需求选择使用相关的算子,这个并是不定死不变的,灵活选择.