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. 解决CSDN文章下载后,依然请求跳转至首页出错的问题

    1. 搜索关键字:"onerror"     然后找到如下所示代码: <div style="display:none;">     <img ...

  2. 学习反射例子,调用DLL窗体及方法

    创建类库,并添加新窗体,加入以下方法 public static string setText(string str) { return str; } 编译后把生成的DLL文件放入新项目的bin目录, ...

  3. 2.设计模式常用的UML图分析(用例图、类图与时序图)

    1-用例图 概述 展现了一组用例.参与者以及他们之间的关系. 用例图从用户角度描述系统的静态使用情况,用于建立需求模型. 用例特征 保证用例能够正确捕捉功能性需求,判断用例是否准确的依据. 用例是动宾 ...

  4. Java数值传递的时候,到底是引用传递还是值传递

    java中既有引用传递也有值传递 ---->>方法形式参数上 1.值传递,基本数据类型 值传递是:传递的是存储单元中的内容,而不是存储单元的引用. 2.引用传递:引用类型,数组,集合. 引 ...

  5. 1.docker概述及其历史

    一. 为什么会出现docker? 不用说, 肯定是时代进步的产物. 那么, 他为什么能火? 一定是解决了痛点问题. docker也不是一下子就火起来了, 他的火也是有一个过程的, 我们先来看看为什么会 ...

  6. docker run配置参数

    Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...] -d, --detach=false 指定容器运行于前台还是后台,默认为false -i, - ...

  7. 在Jupyter Notebook添加代码自动补全功能

    在使用Jupyter notebook时发现没有代码补全功能,于是在网上查找了一些资料,最后总结了以下内容. 1 安装显示目录功能: pip install jupyter_contrib_nbext ...

  8. Php实现简易购物商城系统

    实现功能: 1.系统功能模块包括: 1)登陆注册模块 包括验证码.找回密码.注册模块中要使用Ajax判断用户名是否已经存在,使用正则表达式判断电子邮件.手机号和用户密码的格式是否合法. 2)用户管理模 ...

  9. (转载https://segmentfault.com/a/1190000016313947)了解RestFul Api架构风格设计

    最近几年REST API越来越流行,特别是随着微服务的概念被广泛接受和应用,很多Web Service都使用了REST API. REST是HTTP规范主要编写者之一的Roy Fielding提出的, ...

  10. Jmeter系列(26)- 常用逻辑控制器(5) | 循环控制器Loop Controller

    循环控制器(Loop Controller) 字面意思,循环该控制器下的请求 设定固定循环次数,或者一直循环 同线程组的循环是父子关系,大家可以试下,如果线程组设置了一直循环,而循环控制器设置了2次, ...