java8中有一种新的语法糖,即
lambda表达式,在
flink中,支持对所有的java api提供了 lambda的支持,但是存在一些限制,此处举一个例子,来说明如何在
flink中使用
lambda表达式,以及出错后如何处理。

参考链接:https://ci.apache.org/projects/flink/flink-docs-stable/dev/java_lambdas.html

1、使用lambda的一个示例

/**
* 测试 lambda 表达式在 flink 中的应用
* 不建议使用 lambda 表达式
* <p>
* 参考文章:https://ci.apache.org/projects/flink/flink-docs-stable/dev/java_lambdas.html
*
* @author huan.fu
* @date 2019-11-17 - 13:57
*/
public class FlinkLambdaJob {
public static void main(String[] args) throws Exception {
ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
List<String> datas = Arrays.asList("aa,bb,ccc,dd,aa", "cc,dd,ee,ff,gg,aa");
DataSource<String> dataSource = env.fromCollection(datas);
dataSource.flatMap((String input, Collector<String[]> collector) -> {
collector.collect(input.split(","));
})
.flatMap((String[] words, Collector<Tuple2<String, Integer>> collector) -> {
Arrays.stream(words).map(word -> new Tuple2<>(word, 1)).forEach(collector::collect);
})
.groupBy(0)
.sum(1)
.print();
}
}

2、使用上面这种写法通常或得到如下错误

Exception in thread "main" org.apache.flink.api.common.functions.InvalidTypesException: The return type of function 'main(FlinkLambdaJob.java:26)' could not be determined automatically, due to type erasure. You can give type information hints by using the returns(...) method on the result of the transformation call, or by letting your function implement the 'ResultTypeQueryable' interface.
at org.apache.flink.api.java.DataSet.getType(DataSet.java:178)
at org.apache.flink.api.java.DataSet.flatMap(DataSet.java:266)
at com.huan.study.flink.lambda.FlinkLambdaJob.main(FlinkLambdaJob.java:29)
Caused by: org.apache.flink.api.common.functions.InvalidTypesException: The generic type parameters of 'Collector' are missing. In many cases lambda methods don't provide enough information for automatic type extraction when Java generics are involved. An easy workaround is to use an (anonymous) class instead that implements the 'org.apache.flink.api.common.functions.FlatMapFunction' interface. Otherwise the type has to be specified explicitly using type information.
at org.apache.flink.api.java.typeutils.TypeExtractionUtils.validateLambdaType(TypeExtractionUtils.java:350)
at org.apache.flink.api.java.typeutils.TypeExtractionUtils.extractTypeFromLambda(TypeExtractionUtils.java:176)
at org.apache.flink.api.java.typeutils.TypeExtractor.getUnaryOperatorReturnType(TypeExtractor.java:571)
at org.apache.flink.api.java.typeutils.TypeExtractor.getFlatMapReturnTypes(TypeExtractor.java:196)
at org.apache.flink.api.java.DataSet.flatMap(DataSet.java:266)
at com.huan.study.flink.lambda.FlinkLambdaJob.main(FlinkLambdaJob.java:26)

3、解决方案

默认情况下,flink可以从方法签名中获取范型信息,但是 void flatMap(IN value, Collector<OUT> out)javac编译后,会变成 void flatMap(IN value, Collector out),导致范型丢失,导致flink无法自动推断出类型,flink会认为是Object类型,从而导致无效的序列化类型。

有了以上认识,我们可以提供如下解决方案

1、使用 匿名函数 来替代lambda表达式
2、从报错信息中,我们知道需要使用 returns方法来明确的指定返回类型

修改后的代码,此处使用 returns 方法来实现

4、建议

虽然使用 lambda表达式,在flink中代码变简洁了,但是需要增加额外的returns方法来明确的指定返回值类型,因此建议在flink中尽量少使用lambda表达式,可以使用匿名类来代替。不过这也看个人的习惯。

5、完整代码

https://gitee.com/huan1993/flink-parent/blob/master/flink-lambda/src/main/java/com/huan/study/flink/lambda/FlinkLambdaJob.java

flink中使用lambda表达式的更多相关文章

  1. 你知道C#中的Lambda表达式的演化过程吗

    你知道C#中的Lambda表达式的演化过程吗? 阅读目录 委托的使用 匿名方法 Func和Action Lambda的诞生 那得从很久很久以前说起了,记得那个时候... 懵懂的记得从前有个叫委托的东西 ...

  2. C#中的Lambda表达式和表达式树

    在C# 2.0中,通过方法组转换和匿名方法,使委托的实现得到了极大的简化.但是,匿名方法仍然有些臃肿,而且当代码中充满了匿名方法的时候,可读性可能就会受到影响.C# 3.0中出现的Lambda表达式在 ...

  3. C++11中的Lambda表达式

    原文地址:C++中的Lambda表达式 作者:果冻想 一直都在提醒自己,我是搞C++的:但是当C++11出来这么长时间了,我却没有跟着队伍走,发现很对不起自己的身份,也还好,发现自己也有段时间没有写C ...

  4. Qt5中使用lambda表达式

    c11新特性中加入了lambda表达式,所以Qt 也支持 需在.pro文件中加入 CONFIG += c++11 例子: QString program = "C:/Windows/Syst ...

  5. Lambda 表达式,Java中应用Lambda 表达式

    一.Lambda 表达式 简单来说,编程中提到的 lambda 表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数. 链接:知乎 先举一个普通的 Python 例 ...

  6. 在Linq to sql 和 Entity framework 中使用lambda表达式实现left join

    在Linq to sql 和 Entity framework 中使用lambda表达式实现left join 我们知道lambda表达式在Linq to sql 和 Entity framework ...

  7. Qt5中的lambda表达式和使用lambda来写connect

    c11新特性中加入了lambda表达式,所以Qt 也支持 需在.pro文件中加入 CONFIG += c++11 例子: QString program = "C:/Windows/Syst ...

  8. Android中使用Lambda表达式开发

    参考文章:ImportNew 要在Android开发中使用lambda表达式,首先需要在 Module 的build.gradle中加入: compileOptions { targetCompati ...

  9. 【转】你知道C#中的Lambda表达式的演化过程吗?

    [转]你知道C#中的Lambda表达式的演化过程吗? 那得从很久很久以前说起了,记得那个时候... 懵懂的记得从前有个叫委托的东西是那么的高深难懂. 委托的使用 例一: 什么是委托? 个人理解:用来传 ...

随机推荐

  1. DHCP 协议及其交互过程

    1. DHCP用途简介: DHCP服务应用于大型局域网络中,使网络中的主机自动获取IP地址,网关,DNS服务器等信息,能够提升IP地址的利用率.一般情况下,我们的家用.公司.公共场合使用的路由器都具有 ...

  2. Qt+Python开发百度图片下载器

    一.资源下载地址 https://www.aliyundrive.com/s/jBU2wBS8poH 本项目路径:项目->收费->百度图片下载器(可试用5分钟) 安装包直接下载地址:htt ...

  3. 手把手教你调试SpringBoot启动 IoC容器初始化源码,spring如何解决循环依赖

    授人以鱼不如授人以渔,首先声明这篇文章并没有过多的总结和结论,主要内容是教大家如何一步一步自己手动debug调试源码,然后总结spring如何解决的循环依赖,最后,操作很简单,有手就行. 本次调试 是 ...

  4. Java基础系列(16)- Scanner进阶使用

    了解更多的sanner方法 Ctrl+鼠标左键,点击[Scanner] 点击Structure 看到了Scanner类下面的所有方法,以及具体方法实现的底层封装逻辑 拓展例子_nextInt()获取和 ...

  5. gin 源码阅读(2) - http请求是如何流入gin的?

    推荐阅读: gin 源码阅读(1) - gin 与 net/http 的关系 本篇文章是 gin 源码分析系列的第二篇,这篇文章我们主要弄清一个问题:一个请求通过 net/http 的 socket ...

  6. php 的一些问题

    ------------------------------------------------------------------------------ * 绝对路径转化为相对路径 <?ph ...

  7. [转载]CentOS 下安装LEMP服务(Nginx、MariaDB/MySQL和PHP)

    LEMP 组合包是一款日益流行的网站服务组合软件包,在许多生产环境中的核心网站服务上起着强有力的作用.正如其名称所暗示的, LEMP 包是由 Linux.nginx.MariaDB/MySQL 和 P ...

  8. 浅聊Linux的五种IO模型

    在日常 Coding 中,多多少少都会接触到网络 IO,就会想要深入了解一下.看了很多文章,总是云里雾里的感觉,直到读了<UNIX网络编程 卷1:套接字联网API>中的介绍后,才豁然开朗. ...

  9. 深度学习|基于LSTM网络的黄金期货价格预测--转载

    深度学习|基于LSTM网络的黄金期货价格预测 前些天看到一位大佬的深度学习的推文,内容很适用于实战,争得原作者转载同意后,转发给大家.之后会介绍LSTM的理论知识. 我把code先放在我github上 ...

  10. Ubuntu-mate-20.04-desktop安装总结

    ubuntu-mate-20.04-desktop效果先展示下: Ubuntu用MATE桌面环境同时配合compiz 窗口管理器是目前为止得到的桌面中最喜欢的样式 一.ubuntu-mate官网下载i ...