Flink中使用累加器去记录路口超速车辆信息

首先设定路口超过70km/h为超速车辆

.aggregate(new AggregateFunction<
                    Tuple4<String, Integer, Double, Long>, // 输入元素类型
                    Tuple6<String, Double, Double, Double, Long, Long>, // 累加器类型
                    Tuple5<String, Long, Long, Double, Double> // 输出元素类型
                    >() {
                @Override
                public Tuple6<String, Double, Double, Double, Long, Long> createAccumulator() {
                    return Tuple6.of("", 0.0, 0.0, 0.0, 0L, 0L);
                }

                @Override
                public Tuple6<String, Double, Double, Double, Long, Long> add(
                        Tuple4<String, Integer, Double, Long> value,
                        Tuple6<String, Double, Double, Double, Long, Long> accumulator) {
                    // 第一个元素为车牌号,初始化车牌号和进入路口时间
                    if (accumulator.f0.isEmpty() && value.f1 == 1) {
                        accumulator.f0 = value.f0;
                        accumulator.f4 = value.f3;
                    }
                    // 如果车辆正在路口内超速,则将其纳入计算
                    if (accumulator.f0.equals(value.f0) && value.f1 == 1 && value.f2 > 70.0) {
                        // 求出车辆在路口内的速度总和
                        accumulator.f3 += value.f2;
                        // 更新最高速度
                        if (value.f2 > accumulator.f2) {
                            accumulator.f2 = value.f2;
                        }
                        // 更新路口内时间或离开路口时间
                        if (value.f1 == 1) {
                            accumulator.f5 = value.f3;
                        } else {
                            accumulator.f4 = value.f3;
                        }
                    }
                    return accumulator;
                }

                @Override
                public Tuple5<String, Long, Long, Double, Double> getResult(
                        Tuple6<String, Double, Double, Double, Long, Long> accumulator) {
                    // 结果为:车牌号,进入路口时间,离开路口时间,路口内平均速度,最高速度
                    if (accumulator.f3 > 0) {
                        double avgSpeed = accumulator.f3 / (accumulator.f5 - accumulator.f4) * 1000.0;
                        return Tuple5.of(accumulator.f0, accumulator.f4, accumulator.f5, avgSpeed, accumulator.f2);
                    } else {
                        return null;
                    }
                }

                @Override
                public Tuple6<String, Double, Double, Double, Long, Long> merge(
                        Tuple6<String, Double, Double, Double, Long, Long> a,
                        Tuple6<String, Double, Double, Double, Long, Long> b) {
                    throw new UnsupportedOperationException("不支持merge操作");
                }
            })

在上面的示例中,我们定义了一个 Aggregate Function 累加器,其中 createAccumulator 方法用于创建初始累加器,add 方法用于将元素累加到累加器中,getResult 方法用于返回最终的聚合结果,merge 方法用于合并不同分区的累加器。

在这个示例中,createAccumulator 方法返回 0,因为我们要对分组后的元素求和。add 方法将每个元素的分数累加到累加器中。getResult 方法返回最终的累加值。merge 方法只需要将两个累加器相加即可,因为同一个 Key 的元素只会被分配到同一个分区中。

需要注意的是,上述代码中的累加器函数是对 Key 分组之后的数据进行聚合操作的,因此必须先使用 keyBy() 方法将数据按照 Key 进行分组,否则会抛出运行时异常。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值