【尚硅谷Java版】Flink1.13 转换算子之基本转换算子
- 一、基本转换算子
数据源读入数据以后,我们就可以使用各种转换算子,将一个或多个DataStream转换为新的DataStream。一个Flink程序的核心,其实就是所有二点转换操作,他们决定了处理的业务逻辑。
一、基本转换算子
1、映射map
map是大数据操作算子,主要用于将数据流中的数据进行转换,形成新的数据流。
**简单来说,就是一一对应,消费一个元素就产出一个元素。**如下图所示:
我们只需要基于DataStream调用map()方法
就可以进行转换处理。方法需要传入的参数是接口MapFunction的实现;返回值类型还是DataStream,不过泛型(流中的元素类型)可能改变。
具体使用:
package com.atguigu.chapter05;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import sun.security.mscapi.CPublicKey;
/**
* @author potential
*/
public class TransformMapTest {
public static void main(String[] args) throws Exception {
//1、创建执行环境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
//并行度设置为1
env.setParallelism(1);
//从元素中读取数据
DataStreamSource<Event> stream = env.fromElements(
new Event("Mary", "./home", 1000L),
new Event("Bob", "./cart", 2000L)
);
//进行转换计算,提取user字段
/**
* 1、使用自定义类,实现MapFunction接口
*/
SingleOutputStreamOperator<String> map = stream.map(new MyMapper());
//2、使用匿名类实现MapFunction接口
SingleOutputStreamOperator<String> map1 = stream.map(new MapFunction<Event, String>() {
@Override
public String map(Event event) throws Exception {
return event.user;
}
});
//3、传入Lambda表达式
SingleOutputStreamOperator<String> map2 = stream.map(data -> data.user);
map.print();
map1.print();
map2.print();
env.execute();
}
/**
* 自定义类实现MapFunction接口 MapFunction<T,O>
* MapFunction这个泛型,其中T指的是没有转换之前数据的类型 O指的是转换之后需要输出出去的数据的类型
* 这里 我们没转换之前的数据是Event这个对象 转换之后是Event对象中的元素 于是应该是String
*/
public static class MyMapper implements MapFunction<Event,String>{
@Override
public String map(Event event) throws Exception {
return event.user;
}
}
}
2、过滤 filter
filter作为转换操作,顾名思义是对数据流执行一个过滤,通过一个布尔条件表达式设置过滤条件,对于每一个流内元素进行判断,若为true则元素正常输出,若为false则元素被过滤掉。如下图所示:
进行filter转换之后的新数据流的数据类型与元数据流是相同的
,filter转换需要传入的参数需要实现FilterFunction接口
,而FilterFunction内要实现的filter方法,就相当于返回布尔类型的条件表达式。
具体使用:
package com.atguigu.chapter05;
import org.apache.flink.api.common.functions.FilterFunction;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
/**
* @author potential
*/
public class TransformFilterTest {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(1);
//从元素中读取数据
DataStreamSource<Event> stream = env.fromElements(
new Event("Mary", "./home", 1000L),
new Event("Bob", "./cart", 2000L)
);
//1、传入一个实现了FilterFunction的类的对象
SingleOutputStreamOperator<Event> filter = stream.filter(new MyFilter());
//2、传入一个匿名类实现FilterFunction接口
SingleOutputStreamOperator<Event> filter1 = stream.filter(new FilterFunction<Event>() {
@Override
public boolean filter(Event event) throws Exception {
return event.user.equals("Mary");
}
});
//3、传入lambda表达式
stream.filter(data->data.user.equals("Mary")).print("Mary click");
filter.print();
filter1.print();
env.execute();
}
//实现一个自定义的FilterFunction
public static class MyFilter implements FilterFunction<Event>{
@Override
public boolean filter(Event event) throws Exception {
return event.user.equals("Mary");
}
}
}
测试结果:
3、扁平映射 flatMap
flatMap操作称为扁平映射,主要是将数据流中的整体(一般是集合类型)拆分成一个个的个体
使用。消费一个元素可以产生0~多个元素。
flatMap可以认为是 扁平化+映射
两步操作的集合,也就是先按照某种规则对数据进行打散拆分,再对拆分后的元素转换处理。
具体使用:
package com.atguigu.chapter05;
import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.common.typeinfo.TypeHint;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.util.Collector;
/**
* @author potential
*/
public class TransformFlatMapTest {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(1);
//从元素中读取数据
DataStreamSource<Event> stream = env.fromElements(
new Event("Mary", "./home", 1000L),
new Event("Bob", "./cart", 2000L)
);
//1、实现FlatMapFunction
stream.flatMap(new MyFlatMap()).print("1");
//2、传入一个lambda表达式
stream.flatMap((Event event,Collector<String> out)->{
if(event.user.equals("Mary")) {
out.collect(event.url);
} else if(event.user.equals("Bob")) {
out.collect(event.user);
out.collect(event.url);
out.collect(event.timestamp.toString());
}}).returns(new TypeHint<String>() {
}).print("2");
env.execute();
}
//实现一个自定义的FlatMapFunction
public static class MyFlatMap implements FlatMapFunction<Event,String>{
@Override
public void flatMap(Event event, Collector<String> collector) throws Exception {
collector.collect(event.user);
collector.collect(event.url);
collector.collect(event.timestamp.toString());
}
}
}
测试结果: