【尚硅谷Java版】Flink1.13 转换算子之基本转换算子

  • 一、基本转换算子


        数据源读入数据以后,我们就可以使用各种转换算子,将一个或多个DataStream转换为新的DataStream。一个Flink程序的核心,其实就是所有二点转换操作,他们决定了处理的业务逻辑。

一、基本转换算子

1、映射map

map是大数据操作算子,主要用于将数据流中的数据进行转换,形成新的数据流。

**简单来说,就是一一对应,消费一个元素就产出一个元素。**如下图所示:

flink subtask busy如何处理 flink shade_ide


我们只需要基于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;
            }
        }
}

flink subtask busy如何处理 flink shade_java_02


2、过滤 filter

        filter作为转换操作,顾名思义是对数据流执行一个过滤,通过一个布尔条件表达式设置过滤条件,对于每一个流内元素进行判断,若为true则元素正常输出,若为false则元素被过滤掉。如下图所示:

flink subtask busy如何处理 flink shade_java_03


        进行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");
        }
    }

}

测试结果:

flink subtask busy如何处理 flink shade_flink_04


3、扁平映射 flatMap

       flatMap操作称为扁平映射,主要是将数据流中的整体(一般是集合类型)拆分成一个个的个体使用。消费一个元素可以产生0~多个元素。
       flatMap可以认为是 扁平化+映射两步操作的集合,也就是先按照某种规则对数据进行打散拆分,再对拆分后的元素转换处理。

flink subtask busy如何处理 flink shade_flink_05


具体使用:

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());

            }
    }
   
}

测试结果:

flink subtask busy如何处理 flink shade_apache_06