【Flink-1.17-教程】-【四】Flink DataStream API(2)转换算子(Transformation)【基本转换算子、聚合算子】
数据源读入数据之后,我们就可以使用各种转换算子,将一个或多个 DataStream 转换为新的 DataStream。
1)基本转换算子(map / filter / flatMap)
1.1.映射(map)
map 是大家非常熟悉的大数据操作算子,主要用于将数据流中的数据进行转换,形成新的数据流。简单来说,就是一个“一 一映射”,消费一个元素就产出一个元素。
我们只需要基于 DataStream 调用 map() 方法就可以进行转换处理。方法需要传入的参数是接口 MapFunction 的实现;返回值类型还是 DataStream,不过泛型(流中的元素类型)可能改变。
下面的代码用不同的方式,实现了提取 WaterSensor 中的 id 字段的功能。
public class MapDemo {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(1);
DataStreamSource<WaterSensor> sensorDS = env.fromElements(
new WaterSensor("s1", 1L, 1),
new WaterSensor("s2", 2L, 2),
new WaterSensor("s3", 3L, 3)
);
// TODO map算子: 一进一出
// TODO 方式一: 匿名实现类
// SingleOutputStreamOperator<String> map = sensorDS.map(new MapFunction<WaterSensor, String>() {
// @Override
// public String map(WaterSensor value) throws Exception {
// return value.getId();
// }
// });
// TODO 方式二: lambda表达式
// SingleOutputStreamOperator<String> map = sensorDS.map(sensor -> sensor.getId());
// TODO 方式三: 定义一个类来实现MapFunction
// SingleOutputStreamOperator<String> map = sensorDS.map(new MyMapFunction());
SingleOutputStreamOperator<String> map = sensorDS.map(new MapFunctionImpl());
map.print();
env.execute();
}
public static class MyMapFunction implements MapFunction<WaterSensor,String>{
@Override
public String map(WaterSensor value) throws Exception {
return value.getId();
}
}
}
MapFunctionImpl :
public class MapFunctionImpl implements MapFunction<WaterSensor,String> {
@Override
public String map(WaterSensor value) throws Exception {
return value.getId();
}
}
上面代码中,MapFunction 实现类的泛型类型,与输入数据类型和输出数据的类型有关。在实现 MapFunction 接口的时候,需要指定两个泛型,分别是输入事件和输出事件的类型,还需要重写一个 map() 方法,定义从一个输入事件转换为另一个输出事件的具体逻辑。
1.2.过滤(filter)
filter 转换操作,顾名思义是对数据流执行一个过滤,通过一个布尔条件表达式设置过滤条件,对于每一个流内元素进行判断,若为 true 则元素正常输出,若为 false 则元素被过滤掉。
进行 filter 转换之后的新数据流的数据类型与原数据流是相同的。filter 转换需要传入的参数需要实现 FilterFunction 接口,而 FilterFunction 内要实现 filter() 方法,就相当于一个返回布尔类型的条件表达式。
案例需求:下面的代码会将数据流中传感器 id 为 sensor_1 的数据过滤出来。
public class FilterDemo {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(1);
DataStreamSource<WaterSensor> sensorDS = env.fromElements(
new WaterSensor("s1", 1L, 1),
new WaterSensor("s1", 11L, 11),
new WaterSensor("s2", 2L, 2),
new WaterSensor("s3", 3L, 3)
);
// TODO filter: true保留,false过滤掉
// SingleOutputStreamOperator<WaterSensor> filter = sensorDS.filter(new FilterFunction<WaterSensor>() {
// @Override
// public bo